Compare commits
5 commits
29a453c980
...
75c2755ff2
| Author | SHA1 | Date | |
|---|---|---|---|
| 75c2755ff2 | |||
| 46b8cd8fbf | |||
| 06d3821ce7 | |||
| 40676c83a1 | |||
| cb234aa6ec |
15 changed files with 495 additions and 15 deletions
62
.github/workflows/build.yaml
vendored
Normal file
62
.github/workflows/build.yaml
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
name: Build pico-mac
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
release:
|
||||
types: [published]
|
||||
check_suite:
|
||||
types: [rerequested]
|
||||
|
||||
|
||||
jobs:
|
||||
bins:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install ARM GCC
|
||||
uses: carlosperate/arm-none-eabi-gcc-action@v1
|
||||
with:
|
||||
release: '13.2.Rel1'
|
||||
|
||||
- name: get submodules
|
||||
run: git submodule update --init
|
||||
|
||||
- name: get pico-sdk
|
||||
run: git clone --depth=1 -b adafruit-fruit-jam https://github.com/adafruit/pico-sdk ../pico-sdk && (cd ../pico-sdk && git submodule update --init)
|
||||
|
||||
- name: get pico-extras
|
||||
run: git clone --depth=1 https://github.com/raspberrypi/pico-extras ../pico-extras
|
||||
|
||||
- name: build targets
|
||||
run: |
|
||||
./fruitjam-build.sh
|
||||
mkdir uf2s
|
||||
cp build*/src/*.uf2 uf2s/
|
||||
mkdir elfs
|
||||
cp build*/src/*.elf elfs/
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: uf2 files
|
||||
path: uf2s/*
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: elf files
|
||||
path: elfs/*
|
||||
|
||||
- name: Create release
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
files: uf2s/*
|
||||
fail_on_unmatched_files: true
|
||||
body: "Select a doom_tiny uf2 from the list below, plus the doom1-whx uf2."
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -14,6 +14,7 @@ config.status
|
|||
configure
|
||||
lib
|
||||
obj
|
||||
picotool
|
||||
rpm.spec
|
||||
stamp-h
|
||||
stamp-h.in
|
||||
|
|
@ -30,6 +31,8 @@ HEXEN*.pcx
|
|||
STRIFE*.pcx
|
||||
/build*
|
||||
|
||||
*.uf2
|
||||
|
||||
# These are the default patterns globally ignored by Subversion:
|
||||
*.o
|
||||
*.lo
|
||||
|
|
|
|||
3
.gitmodules
vendored
3
.gitmodules
vendored
|
|
@ -1,3 +1,6 @@
|
|||
[submodule "3rdparty/tinyusb"]
|
||||
path = 3rdparty/tinyusb
|
||||
url = https://github.com/liamfraser/tinyusb.git
|
||||
[submodule "3rdparty/dvhstx"]
|
||||
path = 3rdparty/dvhstx
|
||||
url = https://github.com/jepler/dvhstx
|
||||
|
|
|
|||
1
3rdparty/dvhstx
vendored
Submodule
1
3rdparty/dvhstx
vendored
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 6ae02e64cfe022e79439c9fa848e89936f5ac2a8
|
||||
23
README-fruitjam.md
Normal file
23
README-fruitjam.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# Adafruit Fruit Jam (work in progress)
|
||||
|
||||
* `git submodule update --init`
|
||||
* `sh fruitjam_build.sh`
|
||||
|
||||
You will get binary files including `build_fruitjam/src/doom_tiny.uf2`. and `build_fruitjam/src/doom1-whx-for-fruitjam.uf2`.
|
||||
Copy those two uf2s to fruit jam.
|
||||
You may need to re-enter the bootloader after copying the first file.
|
||||
|
||||
Note: When generating your own whx files, fruit jam ALWAYS uses the offset of 0x10080000.
|
||||
|
||||
You should get:
|
||||
* Debug UART output on pin "A4"
|
||||
* video data on pin 8, sync on 6/7 (I expected data on 9/10 as well but there's not: It's supposed to be 1-bit RGB)
|
||||
* Audio (soundtrack + FX) on I2S
|
||||
|
||||
TODO:
|
||||
* HSTX video
|
||||
* Pico-PIO-USB
|
||||
|
||||
Would be nice:
|
||||
* combined UF2 files
|
||||
* PICO\_NET
|
||||
15
fruitjam-build.sh
Executable file
15
fruitjam-build.sh
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
#!/bin/sh
|
||||
TAG=fruitjam
|
||||
BUILD=build_${TAG}
|
||||
export CFLAGS="-include $(pwd)/fruitjam_cflags.h"
|
||||
export CXXFLAGS="-include $(pwd)/fruitjam_cflags.h"
|
||||
cmake -S . -B $BUILD \
|
||||
-DCMAKE_BUILD_TYPE=MinSizeRel \
|
||||
-DPICO_SDK_PATH=../pico-sdk \
|
||||
-DPICOTOOL_FETCH_FROM_GIT_PATH="$(pwd)/picotool" \
|
||||
-DBOARD=adafruit_fruit_jam -DPICO_BOARD=adafruit_fruit_jam \
|
||||
-DUSE_HSTX=1 \
|
||||
${CMAKE_ARGS} "$@"
|
||||
|
||||
make -C $BUILD -j$(nproc)
|
||||
./picotool/picotool-build/picotool uf2 convert doom1.whx -t bin $BUILD/src/doom1-whx-for-fruitjam.uf2 -o 0x10080000 --family data
|
||||
32
fruitjam_cflags.h
Normal file
32
fruitjam_cflags.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef FRUITJAM_CFLAGS_H
|
||||
#define FRUITJAM_CFLAGS_H 1
|
||||
#define PICO_SCANVIDEO_COLOR_PIN_BASE 8
|
||||
#define PICO_SCANVIDEO_PIXEL_RCOUNT 1
|
||||
#define PICO_SCANVIDEO_PIXEL_GCOUNT 1
|
||||
#define PICO_SCANVIDEO_PIXEL_BCOUNT 1
|
||||
#define PICO_SCANVIDEO_PIXEL_RSHIFT 0
|
||||
#define PICO_SCANVIDEO_PIXEL_GSHIFT 1
|
||||
#define PICO_SCANVIDEO_PIXEL_BSHIFT 2
|
||||
#define PICO_SCANVIDEO_SYNC_PIN_BASE 6
|
||||
#define SD_TX 35
|
||||
#define SD_RX 36
|
||||
#define SD_SCK 34
|
||||
#define SD_CS 39
|
||||
#define USE_SD 1
|
||||
#define USE_HSTX 1
|
||||
#define PICO_DEFAULT_UART 0
|
||||
#define PICO_DEFAULT_UART_TX_PIN 44
|
||||
#define PICO_DEFAULT_UART_RX_PIN 45
|
||||
#define PICO_AUDIO_I2S_DATA_PIN 24
|
||||
#define PICO_AUDIO_I2S_CLOCK_PIN_BASE 26
|
||||
#define HSTX_CKP 11
|
||||
#define HSTX_D0P 13
|
||||
#define HSTX_D1P 15
|
||||
#define HSTX_D2P 17
|
||||
|
||||
// Move the WAD base address way up since we have plenty of flash
|
||||
// Original builds were as low as 0x10040000, this gives an extra 256kB for code since we're chunky
|
||||
#undef TINY_WAD_ADDR
|
||||
#define TINY_WAD_ADDR 0x10080000
|
||||
|
||||
#endif
|
||||
|
|
@ -502,7 +502,7 @@ function(add_doom_tiny SUFFIX RENDER_LIB)
|
|||
# SDK minimilization
|
||||
PICO_TIME_DEFAULT_ALARM_POOL_DISABLED=1
|
||||
PICO_TIME_DEFAULT_ALARM_POOL_MAX_TIMERS=1
|
||||
PICO_DISABLE_SHARED_IRQ_HANDLERS=1
|
||||
# Incompatible with newest sdk: PICO_DISABLE_SHARED_IRQ_HANDLERS=1 https://github.com/raspberrypi/pico-sdk/issues/2626
|
||||
PICO_USE_OPTIMISTIC_SBRK=1
|
||||
|
||||
# MUSIC
|
||||
|
|
|
|||
241
src/i_main.c
241
src/i_main.c
|
|
@ -51,6 +51,241 @@
|
|||
|
||||
void D_DoomMain (void);
|
||||
|
||||
#if defined(ADAFRUIT_FRUIT_JAM)
|
||||
#include "hardware/i2c.h"
|
||||
#define DAC_I2C_ADDR 0x18
|
||||
#define DEBUG_I2C (0)
|
||||
|
||||
static void writeRegister(uint8_t reg, uint8_t value) {
|
||||
uint8_t buf[2];
|
||||
buf[0] = reg;
|
||||
buf[1] = value;
|
||||
int res = i2c_write_timeout_us(i2c0, DAC_I2C_ADDR, buf, sizeof(buf), /* nostop */ false, 1000);
|
||||
if (res != 2) {
|
||||
panic("i2c_write_timeout failed: res=%d\n", res);
|
||||
}
|
||||
if(DEBUG_I2C)
|
||||
printf("Write Reg: %d = 0x%x\n", reg, value);
|
||||
}
|
||||
|
||||
static uint8_t readRegister(uint8_t reg) {
|
||||
uint8_t buf[1];
|
||||
buf[0] = reg;
|
||||
int res = i2c_write_timeout_us(i2c0, DAC_I2C_ADDR, buf, sizeof(buf), /* nostop */ true, 1000);
|
||||
if (res != 1) {
|
||||
if(DEBUG_I2C)
|
||||
printf("res=%d\n", res);
|
||||
panic("i2c_write_timeout failed: res=%d\n", res);
|
||||
}
|
||||
res = i2c_read_timeout_us(i2c0, DAC_I2C_ADDR, buf, sizeof(buf), /* nostop */ false, 1000);
|
||||
if (res != 1) {
|
||||
if(DEBUG_I2C)
|
||||
printf("res=%d\n", res);
|
||||
panic("i2c_read_timeout failed: res=%d\n", res);
|
||||
}
|
||||
uint8_t value = buf[0];
|
||||
if(DEBUG_I2C)
|
||||
printf("Read Reg: %d = 0x%x\n", reg, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
static void modifyRegister(uint8_t reg, uint8_t mask, uint8_t value) {
|
||||
uint8_t current = readRegister(reg);
|
||||
if(DEBUG_I2C)
|
||||
printf("Modify Reg: %d = [Before: 0x%x] with mask 0x%x and value 0x%x\n", reg, current, mask, value);
|
||||
uint8_t new_value = (current & ~mask) | (value & mask);
|
||||
writeRegister(reg, new_value);
|
||||
}
|
||||
|
||||
static void setPage(uint8_t page) {
|
||||
printf("Set page %d\n", page);
|
||||
writeRegister(0x00, page);
|
||||
}
|
||||
|
||||
|
||||
static void Wire_begin() {
|
||||
i2c_init(i2c0, 100000);
|
||||
gpio_set_function(20, GPIO_FUNC_I2C);
|
||||
gpio_set_function(21, GPIO_FUNC_I2C);
|
||||
}
|
||||
|
||||
static void fruitjam_init_i2s(void) {
|
||||
gpio_init(22);
|
||||
gpio_set_dir(22, true);
|
||||
gpio_put(22, true); // allow i2s to come out of reset
|
||||
|
||||
Wire_begin();
|
||||
sleep_ms(1000);
|
||||
|
||||
if(DEBUG_I2C)
|
||||
printf("initialize codec\n");
|
||||
|
||||
// Reset codec
|
||||
writeRegister(0x01, 0x01);
|
||||
sleep_ms(10);
|
||||
|
||||
// Interface Control
|
||||
modifyRegister(0x1B, 0xC0, 0x00);
|
||||
modifyRegister(0x1B, 0x30, 0x00);
|
||||
|
||||
// Clock MUX and PLL settings
|
||||
modifyRegister(0x04, 0x03, 0x03);
|
||||
modifyRegister(0x04, 0x0C, 0x04);
|
||||
|
||||
writeRegister(0x06, 0x20); // PLL J
|
||||
writeRegister(0x08, 0x00); // PLL D LSB
|
||||
writeRegister(0x07, 0x00); // PLL D MSB
|
||||
|
||||
modifyRegister(0x05, 0x0F, 0x02); // PLL P/R
|
||||
modifyRegister(0x05, 0x70, 0x10);
|
||||
|
||||
// DAC/ADC Config
|
||||
modifyRegister(0x0B, 0x7F, 0x08); // NDAC
|
||||
modifyRegister(0x0B, 0x80, 0x80);
|
||||
|
||||
modifyRegister(0x0C, 0x7F, 0x02); // MDAC
|
||||
modifyRegister(0x0C, 0x80, 0x80);
|
||||
|
||||
modifyRegister(0x12, 0x7F, 0x08); // NADC
|
||||
modifyRegister(0x12, 0x80, 0x80);
|
||||
|
||||
modifyRegister(0x13, 0x7F, 0x02); // MADC
|
||||
modifyRegister(0x13, 0x80, 0x80);
|
||||
|
||||
// PLL Power Up
|
||||
modifyRegister(0x05, 0x80, 0x80);
|
||||
|
||||
// Headset and GPIO Config
|
||||
setPage(1);
|
||||
modifyRegister(0x2e, 0xFF, 0x0b);
|
||||
setPage(0);
|
||||
modifyRegister(0x43, 0x80, 0x80); // Headset Detect
|
||||
modifyRegister(0x30, 0x80, 0x80); // INT1 Control
|
||||
modifyRegister(0x33, 0x3C, 0x14); // GPIO1
|
||||
|
||||
|
||||
// DAC Setup
|
||||
modifyRegister(0x3F, 0xC0, 0xC0);
|
||||
|
||||
// DAC Routing
|
||||
setPage(1);
|
||||
modifyRegister(0x23, 0xC0, 0x40);
|
||||
modifyRegister(0x23, 0x0C, 0x04);
|
||||
|
||||
// DAC Volume Control
|
||||
setPage(0);
|
||||
modifyRegister(0x40, 0x0C, 0x00);
|
||||
writeRegister(0x41, 0x28); // Left DAC Vol
|
||||
writeRegister(0x42, 0x28); // Right DAC Vol
|
||||
|
||||
// ADC Setup
|
||||
modifyRegister(0x51, 0x80, 0x80);
|
||||
modifyRegister(0x52, 0x80, 0x00);
|
||||
writeRegister(0x53, 0x68); // ADC Volume
|
||||
|
||||
// Headphone and Speaker Setup
|
||||
setPage(1);
|
||||
modifyRegister(0x1F, 0xC0, 0xC0); // HP Driver
|
||||
modifyRegister(0x28, 0x04, 0x04); // HP Left Gain
|
||||
modifyRegister(0x29, 0x04, 0x04); // HP Right Gain
|
||||
writeRegister(0x24, 0x0A); // Left Analog HP
|
||||
writeRegister(0x25, 0x0A); // Right Analog HP
|
||||
|
||||
modifyRegister(0x28, 0x78, 0x40); // HP Left Gain
|
||||
modifyRegister(0x29, 0x78, 0x40); // HP Right Gain
|
||||
|
||||
// Speaker Amp
|
||||
modifyRegister(0x20, 0x80, 0x80);
|
||||
modifyRegister(0x2A, 0x04, 0x04);
|
||||
modifyRegister(0x2A, 0x18, 0x08);
|
||||
writeRegister(0x26, 0x0A);
|
||||
|
||||
// Return to page 0
|
||||
setPage(0);
|
||||
|
||||
if(DEBUG_I2C)
|
||||
printf("Initialization complete!\n");
|
||||
|
||||
|
||||
// Read all registers for verification
|
||||
if(DEBUG_I2C) {
|
||||
printf("Reading all registers for verification:\n");
|
||||
|
||||
setPage(0);
|
||||
readRegister(0x00); // AIC31XX_PAGECTL
|
||||
readRegister(0x01); // AIC31XX_RESET
|
||||
readRegister(0x03); // AIC31XX_OT_FLAG
|
||||
readRegister(0x04); // AIC31XX_CLKMUX
|
||||
readRegister(0x05); // AIC31XX_PLLPR
|
||||
readRegister(0x06); // AIC31XX_PLLJ
|
||||
readRegister(0x07); // AIC31XX_PLLDMSB
|
||||
readRegister(0x08); // AIC31XX_PLLDLSB
|
||||
readRegister(0x0B); // AIC31XX_NDAC
|
||||
readRegister(0x0C); // AIC31XX_MDAC
|
||||
readRegister(0x0D); // AIC31XX_DOSRMSB
|
||||
readRegister(0x0E); // AIC31XX_DOSRLSB
|
||||
readRegister(0x10); // AIC31XX_MINI_DSP_INPOL
|
||||
readRegister(0x12); // AIC31XX_NADC
|
||||
readRegister(0x13); // AIC31XX_MADC
|
||||
readRegister(0x14); // AIC31XX_AOSR
|
||||
readRegister(0x19); // AIC31XX_CLKOUTMUX
|
||||
readRegister(0x1A); // AIC31XX_CLKOUTMVAL
|
||||
readRegister(0x1B); // AIC31XX_IFACE1
|
||||
readRegister(0x1C); // AIC31XX_DATA_OFFSET
|
||||
readRegister(0x1D); // AIC31XX_IFACE2
|
||||
readRegister(0x1E); // AIC31XX_BCLKN
|
||||
readRegister(0x1F); // AIC31XX_IFACESEC1
|
||||
readRegister(0x20); // AIC31XX_IFACESEC2
|
||||
readRegister(0x21); // AIC31XX_IFACESEC3
|
||||
readRegister(0x22); // AIC31XX_I2C
|
||||
readRegister(0x24); // AIC31XX_ADCFLAG
|
||||
readRegister(0x25); // AIC31XX_DACFLAG1
|
||||
readRegister(0x26); // AIC31XX_DACFLAG2
|
||||
readRegister(0x27); // AIC31XX_OFFLAG
|
||||
readRegister(0x2C); // AIC31XX_INTRDACFLAG
|
||||
readRegister(0x2D); // AIC31XX_INTRADCFLAG
|
||||
readRegister(0x2E); // AIC31XX_INTRDACFLAG2
|
||||
readRegister(0x2F); // AIC31XX_INTRADCFLAG2
|
||||
readRegister(0x30); // AIC31XX_INT1CTRL
|
||||
readRegister(0x31); // AIC31XX_INT2CTRL
|
||||
readRegister(0x33); // AIC31XX_GPIO1
|
||||
readRegister(0x3C); // AIC31XX_DACPRB
|
||||
readRegister(0x3D); // AIC31XX_ADCPRB
|
||||
readRegister(0x3F); // AIC31XX_DACSETUP
|
||||
readRegister(0x40); // AIC31XX_DACMUTE
|
||||
readRegister(0x41); // AIC31XX_LDACVOL
|
||||
readRegister(0x42); // AIC31XX_RDACVOL
|
||||
readRegister(0x43); // AIC31XX_HSDETECT
|
||||
readRegister(0x51); // AIC31XX_ADCSETUP
|
||||
readRegister(0x52); // AIC31XX_ADCFGA
|
||||
readRegister(0x53); // AIC31XX_ADCVOL
|
||||
|
||||
setPage(1);
|
||||
readRegister(0x1F); // AIC31XX_HPDRIVER
|
||||
readRegister(0x20); // AIC31XX_SPKAMP
|
||||
readRegister(0x21); // AIC31XX_HPPOP
|
||||
readRegister(0x22); // AIC31XX_SPPGARAMP
|
||||
readRegister(0x23); // AIC31XX_DACMIXERROUTE
|
||||
readRegister(0x24); // AIC31XX_LANALOGHPL
|
||||
readRegister(0x25); // AIC31XX_RANALOGHPR
|
||||
readRegister(0x26); // AIC31XX_LANALOGSPL
|
||||
readRegister(0x27); // AIC31XX_RANALOGSPR
|
||||
readRegister(0x28); // AIC31XX_HPLGAIN
|
||||
readRegister(0x29); // AIC31XX_HPRGAIN
|
||||
readRegister(0x2A); // AIC31XX_SPLGAIN
|
||||
readRegister(0x2B); // AIC31XX_SPRGAIN
|
||||
readRegister(0x2C); // AIC31XX_HPCONTROL
|
||||
readRegister(0x2E); // AIC31XX_MICBIAS
|
||||
readRegister(0x2F); // AIC31XX_MICPGA
|
||||
readRegister(0x30); // AIC31XX_MICPGAPI
|
||||
readRegister(0x31); // AIC31XX_MICPGAMI
|
||||
readRegister(0x32); // AIC31XX_MICPGACM
|
||||
|
||||
setPage(3);
|
||||
readRegister(0x10); // AIC31XX_TIMERDIVIDER
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#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"));
|
||||
|
|
@ -73,11 +308,17 @@ int main(int argc, char **argv)
|
|||
((rxdelay << QMI_M0_TIMING_RXDELAY_LSB) & QMI_M0_TIMING_RXDELAY_BITS),
|
||||
QMI_M0_TIMING_CLKDIV_BITS | QMI_M0_TIMING_RXDELAY_BITS
|
||||
);
|
||||
#if defined(ADAFRUIT_FRUIT_JAM)
|
||||
fruitjam_init_i2s();
|
||||
#endif
|
||||
#endif
|
||||
#if !USE_HSTX
|
||||
// hstx is in charge of all clocking
|
||||
vreg_set_voltage(VREG_VOLTAGE_1_30);
|
||||
busy_wait_us(1000);
|
||||
// todo pause? is this the cause of the cold start issue?
|
||||
set_sys_clock_khz(270000, true);
|
||||
#endif
|
||||
#if !USE_PICO_NET
|
||||
// debug ?
|
||||
// gpio_debug_pins_init();
|
||||
|
|
|
|||
|
|
@ -38,8 +38,19 @@ target_compile_definitions(common_pico INTERFACE
|
|||
PICO_USE_STACK_GUARDS=0 # todo we can actually use these sensibly, but right now we do overflow!
|
||||
)
|
||||
|
||||
pico_generate_pio_header(common_pico ${CMAKE_CURRENT_LIST_DIR}/video_doom.pio)
|
||||
target_link_libraries(common_pico INTERFACE pico_stdlib pico_multicore pico_scanvideo_dpi)
|
||||
target_link_libraries(common_pico INTERFACE pico_stdlib pico_multicore)
|
||||
|
||||
if (USE_HSTX)
|
||||
target_sources(common_pico INTERFACE
|
||||
${CMAKE_CURRENT_LIST_DIR}/dvhstx_shim.cpp)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/../../3rdparty/dvhstx/drivers/dvhstx/dvhstx.cmake)
|
||||
target_link_libraries(common_pico INTERFACE dvhstx)
|
||||
target_compile_definitions(common_pico INTERFACE USE_HSTX=1)
|
||||
else()
|
||||
pico_generate_pio_header(common_pico ${CMAKE_CURRENT_LIST_DIR}/video_doom.pio)
|
||||
target_link_libraries(common_pico INTERFACE pico_scanvideo_dpi)
|
||||
target_compile_definitions(common_pico INTERFACE USE_HSTX=0)
|
||||
endif()
|
||||
|
||||
add_library(pico_cd INTERFACE)
|
||||
if (TARGET tinyusb_host)
|
||||
|
|
|
|||
8
src/pico/dvhstx_shim.cpp
Normal file
8
src/pico/dvhstx_shim.cpp
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#include "dvhstx.hpp"
|
||||
#include "dvhstx_shim.h"
|
||||
|
||||
static pimoroni::DVHSTX display;
|
||||
void hstx_setup(line_fun_t gen_line) {
|
||||
display.set_callback(gen_line, &display);
|
||||
display.init(640, 240, pimoroni::DVHSTX::MODE_LINE_CALLBACK_RGB565, {HSTX_CKP, HSTX_D0P, HSTX_D1P, HSTX_D2P});
|
||||
}
|
||||
12
src/pico/dvhstx_shim.h
Normal file
12
src/pico/dvhstx_shim.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void(*line_fun_t)(void *cb_data, int line_num, uint32_t *data);
|
||||
void hstx_setup(line_fun_t gen_line);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
@ -465,11 +465,7 @@ void I_BindInputVariables(void)
|
|||
M_BindIntVariable("novert", &novert);
|
||||
}
|
||||
|
||||
#if PICO_NO_HARDWARE
|
||||
#include "pico/scanvideo.h"
|
||||
#else
|
||||
#define WITH_SHIFT 0x8000
|
||||
#endif
|
||||
|
||||
static void pico_key_down(int scancode, int keysym, int modifiers) {
|
||||
event_t event;
|
||||
|
|
|
|||
|
|
@ -43,22 +43,36 @@
|
|||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
#if USE_HSTX
|
||||
#if !PICO_ON_DEVICE
|
||||
#error Do not set USE_HSTX when !ON_DEVICE (only scanvideo is implemented)
|
||||
#endif
|
||||
#else
|
||||
#include "pico/scanvideo.h"
|
||||
#include "pico/scanvideo/composable_scanline.h"
|
||||
#endif
|
||||
#include "pico/multicore.h"
|
||||
#include "pico/sync.h"
|
||||
#include "pico/time.h"
|
||||
#include "hardware/gpio.h"
|
||||
#include "picodoom.h"
|
||||
#include "video_doom.pio.h"
|
||||
#include "image_decoder.h"
|
||||
#if PICO_ON_DEVICE
|
||||
#include "hardware/dma.h"
|
||||
#include "hardware/structs/xip_ctrl.h"
|
||||
#endif
|
||||
|
||||
#define YELLOW_SUBMARINE 0
|
||||
#if USE_HSTX
|
||||
#include "dvhstx_shim.h"
|
||||
#undef SUPPORT_TEXT
|
||||
#define SUPPORT_TEXT 0
|
||||
#define PICO_SCANVIDEO_PIXEL_FROM_RGB8(r,g,b) (((r) << 16) | ((g) << 8) | (b))
|
||||
#else
|
||||
#include "video_doom.pio.h"
|
||||
#define SUPPORT_TEXT 1
|
||||
#endif
|
||||
|
||||
#define YELLOW_SUBMARINE 0
|
||||
#if SUPPORT_TEXT
|
||||
typedef struct __packed {
|
||||
const char * const name;
|
||||
|
|
@ -91,7 +105,7 @@ static uint16_t ega_colors[] = {
|
|||
|
||||
// todo temproarly turned this off because it causes a seeming bug in scanvideo (perhaps only with the new callback stuff) where the last repeated scanline of a pixel line is freed while shown
|
||||
// note it may just be that this happens anyway, but usually we are writing slower than the beam?
|
||||
#define USE_INTERP PICO_ON_DEVICE
|
||||
#define USE_INTERP PICO_ON_DEVICE && !USE_HSTX
|
||||
#if USE_INTERP
|
||||
#include "hardware/interp.h"
|
||||
#endif
|
||||
|
|
@ -141,6 +155,7 @@ static uint32_t *text_scanline_buffer_start;
|
|||
static uint8_t *text_screen_cpy;
|
||||
static uint8_t *text_font_cpy;
|
||||
|
||||
#if !USE_HSTX
|
||||
#if USE_1280x1024x60
|
||||
//static uint32_t missing_scanline_data[] = {
|
||||
// video_doom_offset_raw_1p | (0 << 16u),
|
||||
|
|
@ -267,6 +282,7 @@ static inline void interp_restore_static(interp_hw_t *interp, interp_hw_save_t *
|
|||
interp->ctrl[1] = saver->ctrl[1];
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void I_ShutdownGraphics(void)
|
||||
{
|
||||
|
|
@ -980,6 +996,56 @@ void __no_inline_not_in_flash_func(new_frame_stuff)() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#if USE_HSTX
|
||||
void __scratch_x("scanlines") gen_line(void *cb_data, int scanline, uint32_t *dest) {
|
||||
if(scanline == 0) {
|
||||
new_frame_stuff();
|
||||
}
|
||||
|
||||
DEBUG_PINS_SET(scanline_copy, 1);
|
||||
if (display_video_type != VIDEO_TYPE_TEXT) {
|
||||
scanline_funcs[display_video_type](dest, scanline);
|
||||
if (display_video_type >= FIRST_VIDEO_TYPE_WITH_OVERLAYS) {
|
||||
assert(scanline < count_of(vpatchlists->vpatch_starters));
|
||||
int prev = 0;
|
||||
for (int vp = vpatchlists->vpatch_starters[scanline]; vp;) {
|
||||
int next = vpatchlists->vpatch_next[vp];
|
||||
while (vpatchlists->vpatch_next[prev] && vpatchlists->vpatch_next[prev] < vp) {
|
||||
prev = vpatchlists->vpatch_next[prev];
|
||||
}
|
||||
assert(prev != vp);
|
||||
assert(vpatchlists->vpatch_next[prev] != vp);
|
||||
vpatchlists->vpatch_next[vp] = vpatchlists->vpatch_next[prev];
|
||||
vpatchlists->vpatch_next[prev] = vp;
|
||||
prev = vp;
|
||||
vp = next;
|
||||
}
|
||||
vpatchlist_t *overlays = vpatchlists->overlays[display_overlay_index];
|
||||
prev = 0;
|
||||
for (int vp = vpatchlists->vpatch_next[prev]; vp; vp = vpatchlists->vpatch_next[prev]) {
|
||||
patch_t *patch = resolve_vpatch_handle(overlays[vp].entry.patch_handle);
|
||||
int yoff = scanline - overlays[vp].entry.y;
|
||||
if (yoff < vpatch_height(patch)) {
|
||||
vpatchlists->vpatch_doff[vp] = draw_vpatch((uint16_t*)(dest), patch, &overlays[vp],
|
||||
vpatchlists->vpatch_doff[vp]);
|
||||
prev = vp;
|
||||
} else {
|
||||
vpatchlists->vpatch_next[prev] = vpatchlists->vpatch_next[vp];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#if 0 // SUPPORT_TEXT doesn't work with dvhstx
|
||||
render_text_mode_scanline(buffer, scanline);
|
||||
#else
|
||||
memset(dest, 0, SCREENWIDTH * 2);
|
||||
#endif
|
||||
}
|
||||
DEBUG_PINS_CLR(scanline_copy, 1);
|
||||
}
|
||||
|
||||
#else
|
||||
void __scratch_x("scanlines") fill_scanlines() {
|
||||
#if SUPPORT_TEXT
|
||||
struct scanvideo_scanline_buffer *buffer = scanvideo_begin_scanline_generation_linked(display_video_type == VIDEO_TYPE_TEXT ? 2 : 1, false);
|
||||
|
|
@ -1069,6 +1135,7 @@ void __scratch_x("scanlines") fill_scanlines() {
|
|||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#pragma GCC pop_options
|
||||
|
||||
#if PICO_ON_DEVICE
|
||||
|
|
@ -1088,6 +1155,9 @@ static void __not_in_flash_func(free_buffer_callback)() {
|
|||
|
||||
//static semaphore_t init_sem;
|
||||
static void core1() {
|
||||
#if USE_HSTX
|
||||
hstx_setup(gen_line);
|
||||
#else
|
||||
#if !PICO_ON_DEVICE
|
||||
void simulate_video_pio_video_doom(const uint32_t *dma_data, uint32_t dma_data_size,
|
||||
uint16_t *pixel_buffer, int32_t max_pixels, int32_t expected_width, bool overlay);
|
||||
|
|
@ -1113,6 +1183,7 @@ static void core1() {
|
|||
fill_scanlines();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if PICO_RP2350
|
||||
|
|
@ -1386,6 +1457,7 @@ void I_DisplayFPSDots(boolean dots_on)
|
|||
{
|
||||
}
|
||||
|
||||
#if !USE_HSTX
|
||||
#if PICO_ON_DEVICE
|
||||
bool video_doom_adapt_for_mode(const struct scanvideo_pio_program *program, const struct scanvideo_mode *mode,
|
||||
struct scanvideo_scanline_buffer *missing_scanvideo_scanline_buffer, uint16_t *modifiable_instructions) {
|
||||
|
|
@ -1516,5 +1588,6 @@ void simulate_video_pio_video_doom(const uint32_t *dma_data, uint32_t dma_data_s
|
|||
assert(last_was_black);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -90,7 +90,7 @@ static wad_file_t *W_Memory_OpenFile(const char *path)
|
|||
}
|
||||
#endif
|
||||
#endif
|
||||
return &fileo;
|
||||
return (wad_file_t *)&fileo;
|
||||
}
|
||||
|
||||
static void W_Memory_CloseFile(wad_file_t *wad)
|
||||
|
|
|
|||
Loading…
Reference in a new issue