mirror of
https://github.com/fruit-bat/pico-zxspectrum.git
synced 2025-04-19 00:04:01 +03:00
commit
a34c827005
@ -42,7 +42,9 @@ pico_sdk_init()
|
||||
add_compile_definitions(PICO_MCU="${PICO_PLATFORM}")
|
||||
|
||||
add_compile_options(-Wall)
|
||||
add_definitions(-DHID_PROTOCOL_DEFAULT=HID_PROTOCOL_REPORT)
|
||||
|
||||
add_compile_definitions(HID_PROTOCOL_DEFAULT=HID_PROTOCOL_REPORT)
|
||||
add_compile_definitions(PICO_FLASH_SPI_CLKDIV=6)
|
||||
|
||||
set(DVI_DEFAULT_SERIAL_CONFIG "pico_sock_cfg" CACHE STRING
|
||||
"Select a default pin configuration from common_dvi_pin_configs.h")
|
||||
|
@ -23,6 +23,14 @@ This project is intended to be relatively easy to breadboard or prototype in som
|
||||
|
||||
## Updates
|
||||
|
||||
27/12/24
|
||||
|
||||
* Additions for Murmulator 2 (only mono PWM audio for now)
|
||||
* Vcore and Vsys displayed on menu
|
||||
* PIO PWM mono audio for some builds
|
||||
|
||||
The move to PWM audio is primarily to support the RP2350, on which I have been having problems with the timer interrupts. There were also some stability issues on the RP2040 particularly with the 270Mhz overclock. Anyhow, I think the sound quality is much better using the PIO, probably because the delivery of samples is done in sync with the PWM frame. The down side is I am only doing mono for now; I have run out of PIO state-machines on the RP2040, but the RP2350 has an extra PIO block so I may have a go at stereo just for the RP2350.
|
||||
|
||||
23/11/24
|
||||
|
||||
* Better beeper sound quality (Mark II)
|
||||
@ -101,6 +109,7 @@ Click on the images below for more information ...
|
||||
| [HDMI + key matrix](docs/ZxSpectrumBreadboardHdmiKbd1PinAudio.md) | Breadboard with key matrix support |
|
||||
| [ArnoldUK](docs/ZxSpectrumPicomputerVgaAuk.md) | Arnold UK's board |
|
||||
| [MURMULATOR](docs/MURMULATOR.md) | Micro with VGA/HDMI and more |
|
||||
| [MURMULATOR2](docs/MURMULATOR2.md) | Micro with VGA/HDMI and more |
|
||||
| [RP2040-PiZero](docs/ZxSpectrumPiZero.md) | Waveshare RP2040-PiZero Development Board |
|
||||
|
||||
## Screen shots
|
||||
|
26
docs/MURMULATOR2.md
Normal file
26
docs/MURMULATOR2.md
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
### MURMULATOR2 platform
|
||||
|
||||
<img src="MURMULATOR2_pic.JPG" width="400"/>
|
||||
|
||||
#### Circuit diagram
|
||||
<img src="MURMULATOR2_circuit.jpeg" height="300"/>
|
||||
|
||||
#### Pin assignments
|
||||
<img src="MURMULATOR2_pins.png" height="500"/>
|
||||
|
||||
#### Firmware
|
||||
| Video | Audio | Display mode | Firmware Pico | Firmware Pico2 |
|
||||
| - | - | - | - | - |
|
||||
| HDMI | HDMI | 720x576x50Hz | [ZX-MURMULATOR2_HDMI_HDMI_AUDIO_720x576x50Hz.uf2](/uf2-rp2040/ZX-MURMULATOR2_HDMI_HDMI_AUDIO_720x576x50Hz.uf2) | [ZX-MURMULATOR2_HDMI_HDMI_AUDIO_720x576x50Hz.uf2](/uf2-rp2350-arm-s/ZX-MURMULATOR2_HDMI_HDMI_AUDIO_720x576x50Hz.uf2) |
|
||||
| HDMI | PWM | 720x576x50Hz | [ZX-MURMULATOR2_HDMI_PWM_AUDIO_720x576x50Hz.uf2](/uf2-rp2040/ZX-MURMULATOR2_HDMI_PWM_AUDIO_720x576x50Hz.uf2) | [ZX-MURMULATOR2_HDMI_PWM_AUDIO_720x576x50Hz.uf2](/uf2-rp2350-arm-s/ZX-MURMULATOR2_HDMI_PWM_AUDIO_720x576x50Hz.uf2) |
|
||||
| HDMI | I2S | 720x576x50Hz | [ZX-MURMULATOR2_HDMI_I2S_AUDIO_720x576x50Hz.uf2](/uf2-rp2040/ZX-MURMULATOR2_HDMI_I2S_AUDIO_720x576x50Hz.uf2) | [ZX-MURMULATOR2_HDMI_I2S_AUDIO_720x576x50Hz.uf2](/uf2-rp2350-arm-s/ZX-MURMULATOR2_HDMI_I2S_AUDIO_720x576x50Hz.uf2) |
|
||||
| HDMI | HDMI | 640x480x60Hz | [ZX-MURMULATOR2_HDMI_HDMI_AUDIO_640x480x60Hz.uf2](/uf2-rp2040/ZX-MURMULATOR2_HDMI_HDMI_AUDIO_640x480x60Hz.uf2) | [ZX-MURMULATOR2_HDMI_HDMI_AUDIO_640x480x60Hz.uf2](/uf2-rp2350-arm-s/ZX-MURMULATOR2_HDMI_HDMI_AUDIO_640x480x60Hz.uf2) |
|
||||
| HDMI | PWM | 640x480x60Hz | [ZX-MURMULATOR2_HDMI_PWM_AUDIO_640x480x60Hz.uf2](/uf2-rp2040/ZX-MURMULATOR2_HDMI_PWM_AUDIO_640x480x60Hz.uf2) | [ZX-MURMULATOR2_HDMI_PWM_AUDIO_640x480x60Hz.uf2](/uf2-rp2350-arm-s/ZX-MURMULATOR2_HDMI_PWM_AUDIO_640x480x60Hz.uf2) |
|
||||
| HDMI | I2S | 640x480x60Hz | [ZX-MURMULATOR2_HDMI_I2S_AUDIO_640x480x60Hz.uf2](/uf2-rp2040/ZX-MURMULATOR2_HDMI_I2S_AUDIO_640x480x60Hz.uf2) | [ZX-MURMULATOR2_HDMI_I2S_AUDIO_640x480x60Hz.uf2](/uf2-rp2350-arm-s/ZX-MURMULATOR2_HDMI_I2S_AUDIO_640x480x60Hz.uf2) |
|
||||
| VGA | PWM | 720x576x50Hz |[ZX-MURMULATOR2_VGA_PWM_AUDIO_720x576x50Hz.uf2](/uf2-rp2040/ZX-MURMULATOR2_VGA_PWM_AUDIO_720x576x50Hz.uf2) | [ZX-MURMULATOR2_VGA_PWM_AUDIO_720x576x50Hz.uf2](/uf2-rp2350-arm-s/ZX-MURMULATOR2_VGA_PWM_AUDIO_720x576x50Hz.uf2) |
|
||||
| VGA | I2S | 720x576x50Hz |[ZX-MURMULATOR2_VGA_I2S_AUDIO_720x576x50Hz.uf2](/uf2-rp2040/ZX-MURMULATOR2_VGA_I2S_AUDIO_720x576x50Hz.uf2) | [ZX-MURMULATOR2_VGA_I2S_AUDIO_720x576x50Hz.uf2](/uf2-rp2350-arm-s/ZX-MURMULATOR2_VGA_I2S_AUDIO_720x576x50Hz.uf2) |
|
||||
| VGA | PWM | 640x480x60Hz |[ZX-MURMULATOR2_VGA_PWM_AUDIO_640x480x60Hz.uf2](/uf2-rp2040/ZX-MURMULATOR2_VGA_PWM_AUDIO_640x480x60Hz.uf2) | [ZX-MURMULATOR2_VGA_PWM_AUDIO_640x480x60Hz.uf2](/uf2-rp2350-arm-s/ZX-MURMULATOR2_VGA_PWM_AUDIO_640x480x60Hz.uf2) |
|
||||
| VGA | I2S | 640x480x60Hz |[ZX-MURMULATOR2_VGA_I2S_AUDIO_640x480x60Hz.uf2](/uf2-rp2040/ZX-MURMULATOR2_VGA_I2S_AUDIO_640x480x60Hz.uf2) | [ZX-MURMULATOR2_VGA_I2S_AUDIO_640x480x60Hz.uf2](/uf2-rp2350-arm-s/ZX-MURMULATOR2_VGA_I2S_AUDIO_640x480x60Hz.uf2) |
|
||||
|
||||
#### References
|
BIN
docs/MURMULATOR2_circuit.jpeg
Normal file
BIN
docs/MURMULATOR2_circuit.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 MiB |
BIN
docs/MURMULATOR2_pic.JPG
Normal file
BIN
docs/MURMULATOR2_pic.JPG
Normal file
Binary file not shown.
After Width: | Height: | Size: 170 KiB |
BIN
docs/MURMULATOR2_pins.png
Normal file
BIN
docs/MURMULATOR2_pins.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 194 KiB |
@ -88,6 +88,9 @@ set(zxspectrum_common_libs
|
||||
hardware_dma
|
||||
hardware_flash # Needed for flash settings (not currently working)
|
||||
hardware_sync # Needed for flash settings (not currently working)
|
||||
hardware_pio
|
||||
hardware_pwm
|
||||
hardware_adc
|
||||
Zeta
|
||||
Z80
|
||||
)
|
||||
@ -100,13 +103,8 @@ set(zxspectrum_ear_in_pio
|
||||
${CMAKE_CURRENT_LIST_DIR}/zx_ear_in.pio
|
||||
)
|
||||
|
||||
set(murmulator_common_src
|
||||
${CMAKE_CURRENT_LIST_DIR}/ps2kbd_mrmltr.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/ps2kbd_mrmltr.h
|
||||
)
|
||||
|
||||
set(murmulator_ps2kbd_pio
|
||||
${CMAKE_CURRENT_LIST_DIR}/ps2kbd_mrmltr.pio
|
||||
set(zxspectrum_pwm_pio
|
||||
${CMAKE_CURRENT_LIST_DIR}/pwm.pio
|
||||
)
|
||||
|
||||
add_subdirectory(hdmi)
|
||||
@ -137,6 +135,27 @@ if ((${PICO_BOARD} STREQUAL "pico") OR (${PICO_BOARD} STREQUAL "pico2"))
|
||||
add_dependencies(relevant ZX-MURMULATOR)
|
||||
endif()
|
||||
|
||||
########################################################################
|
||||
# MURMULATOR2 (RP2040 or RP2350)
|
||||
########################################################################
|
||||
add_custom_target(ZX-MURMULATOR2)
|
||||
add_dependencies(ZX-MURMULATOR2
|
||||
ZX-MURMULATOR2_HDMI_PWM_AUDIO_640x480x60Hz
|
||||
ZX-MURMULATOR2_HDMI_PWM_AUDIO_720x576x50Hz
|
||||
ZX-MURMULATOR2_HDMI_HDMI_AUDIO_640x480x60Hz
|
||||
ZX-MURMULATOR2_HDMI_HDMI_AUDIO_720x576x50Hz
|
||||
ZX-MURMULATOR2_HDMI_I2S_AUDIO_640x480x60Hz
|
||||
ZX-MURMULATOR2_HDMI_I2S_AUDIO_720x576x50Hz
|
||||
ZX-MURMULATOR2_VGA_PWM_AUDIO_640x480x60Hz
|
||||
ZX-MURMULATOR2_VGA_PWM_AUDIO_720x576x50Hz
|
||||
ZX-MURMULATOR2_VGA_I2S_AUDIO_640x480x60Hz
|
||||
ZX-MURMULATOR2_VGA_I2S_AUDIO_720x576x50Hz
|
||||
)
|
||||
if ((${PICO_BOARD} STREQUAL "pico") OR (${PICO_BOARD} STREQUAL "pico2"))
|
||||
message("Relevant target: ZX-MURMULATOR2")
|
||||
add_dependencies(relevant ZX-MURMULATOR2)
|
||||
endif()
|
||||
|
||||
########################################################################
|
||||
# Breadboard (RP2040 or RP2350)
|
||||
########################################################################
|
||||
|
@ -850,6 +850,7 @@ uint32_t __not_in_flash_func(ZxSpectrum::step)()
|
||||
{
|
||||
// Time for a single audio out sample in 32nds of a micro second
|
||||
const int32_t u32pas = ((1000000 << 5) / PICO_AUDIO_OUT_FREQ);
|
||||
// 90%: const int32_t u32pas = (90UL * (1000000UL << 5UL)) / (PICO_AUDIO_OUT_FREQ * 100UL);
|
||||
|
||||
const uint32_t c = z80Step(32);
|
||||
uint32_t vA, vB, vC;
|
||||
|
@ -1,13 +1,48 @@
|
||||
#include "ZxSpectrumAudio.h"
|
||||
#include "hardware/gpio.h"
|
||||
#include "hardware/clocks.h"
|
||||
#include "pico/printf.h"
|
||||
|
||||
#ifndef INITIAL_VOL
|
||||
#define INITIAL_VOL 0x100
|
||||
#endif
|
||||
static uint32_t _vol = INITIAL_VOL;
|
||||
|
||||
#if !defined(PICO_HDMI_AUDIO) && !defined(PICO_AUDIO_I2S)
|
||||
#if defined(PICO_PIO_PWM_AUDIO)
|
||||
|
||||
#include "pwm.pio.h"
|
||||
static uint pwm_audio_sm = 0;
|
||||
|
||||
// Write `period` to the input shift register
|
||||
void pio_pwm_set_period(PIO pio, uint sm, uint32_t period) {
|
||||
pio_sm_set_enabled(pio, sm, false);
|
||||
pio_sm_put_blocking(pio, sm, period);
|
||||
pio_sm_exec(pio, sm, pio_encode_pull(false, false));
|
||||
pio_sm_exec(pio, sm, pio_encode_out(pio_isr, 32));
|
||||
pio_sm_set_enabled(pio, sm, true);
|
||||
}
|
||||
|
||||
void init_pio_pwm_audio() {
|
||||
|
||||
gpio_init(SPK_PIN);
|
||||
gpio_set_dir(SPK_PIN, GPIO_OUT);
|
||||
|
||||
uint offset = pio_add_program(PICO_AUDIO_PWM_PIO, &pwm_program);
|
||||
printf("Loaded PWM PIO at %u\n", offset);
|
||||
pwm_audio_sm = pio_claim_unused_sm(PICO_AUDIO_PWM_PIO, true);
|
||||
printf("Chosen %d for PWM PIO State machine\n", pwm_audio_sm);
|
||||
pwm_program_init(PICO_AUDIO_PWM_PIO, pwm_audio_sm, offset, SPK_PIN);
|
||||
pio_sm_set_clkdiv(PICO_AUDIO_PWM_PIO, pwm_audio_sm, 2.0);
|
||||
pio_pwm_set_period(PICO_AUDIO_PWM_PIO, pwm_audio_sm, 1024);
|
||||
printf("Finish configuring PWM PIO\n");
|
||||
}
|
||||
|
||||
// Write `level` to TX FIFO. State machine will copy this into X.
|
||||
inline void pio_pwm_set_level(PIO pio, uint sm, uint32_t level) {
|
||||
pio_sm_put_blocking(pio, sm, level);
|
||||
}
|
||||
|
||||
#elif !defined(PICO_HDMI_AUDIO) && !defined(PICO_AUDIO_I2S)
|
||||
#include "pico/time.h"
|
||||
// PWM Audio stuff
|
||||
#define ZX_AUDIO_BUF_SIZE_BITS 7
|
||||
@ -58,15 +93,30 @@ inline zx_audio_sample_t *zx_audio_buf_write_ptr(zx_audio_buf_t *b) {
|
||||
return &b->sample[b->wi];
|
||||
}
|
||||
|
||||
|
||||
#ifdef BZR_PIN
|
||||
#ifdef AY8912_A_PIN
|
||||
#ifdef AY8912_ABC_STEREO
|
||||
#define PWM_WRAP (255 + 255)
|
||||
#else
|
||||
#define PWM_WRAP (255)
|
||||
#endif
|
||||
#else
|
||||
#define PWM_WRAP (255 + 255 + 255)
|
||||
#endif
|
||||
#else
|
||||
#define PWM_WRAP (255 + 255 + 255)
|
||||
#endif
|
||||
|
||||
static zx_audio_buf_t zx_audio_buf;
|
||||
static struct repeating_timer timer;
|
||||
bool repeating_timer_callback(struct repeating_timer *timer)
|
||||
bool __not_in_flash_func(repeating_timer_callback)(struct repeating_timer *timer)
|
||||
{
|
||||
static zx_audio_sample_t last;
|
||||
uint32_t vA;
|
||||
uint32_t vB;
|
||||
uint32_t vC;
|
||||
uint32_t s;
|
||||
int32_t s;
|
||||
uint32_t buzzer;
|
||||
|
||||
if (zx_audio_buf_ready_for_read(&zx_audio_buf))
|
||||
@ -109,30 +159,16 @@ bool repeating_timer_callback(struct repeating_timer *timer)
|
||||
pwm_set_gpio_level(AY8912_A_PIN, lt);
|
||||
pwm_set_gpio_level(AY8912_C_PIN, rt);
|
||||
pwm_set_gpio_level(SPK_PIN, st);
|
||||
#else
|
||||
#else
|
||||
uint32_t ayt = __mul_instruction(_vol, vA + vB + vC) >> 8;
|
||||
uint32_t ss = __mul_instruction(_vol, s) >> 8;
|
||||
uint32_t t = ayt + ss;
|
||||
uint32_t t = ayt + ss + 128;
|
||||
pwm_set_gpio_level(SPK_PIN, t >= 255 + 255 + 255 ? ayt - ss : t);
|
||||
#endif
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef BZR_PIN
|
||||
#ifdef AY8912_A_PIN
|
||||
#ifdef AY8912_ABC_STEREO
|
||||
#define PWM_WRAP (255 + 255)
|
||||
#else
|
||||
#define PWM_WRAP (255)
|
||||
#endif
|
||||
#else
|
||||
#define PWM_WRAP (255 + 255 + 255)
|
||||
#endif
|
||||
#else
|
||||
#define PWM_WRAP (255 + 255 + 255)
|
||||
#endif
|
||||
|
||||
static void init_pwm_pin(uint32_t pin) {
|
||||
gpio_set_function(pin, GPIO_FUNC_PWM);
|
||||
const int audio_pin_slice = pwm_gpio_to_slice_num(pin);
|
||||
@ -248,8 +284,9 @@ bool __not_in_flash_func(zxSpectrumEarReady)() {
|
||||
}
|
||||
|
||||
void zxSpectrumAudioInit() {
|
||||
|
||||
#if defined(PICO_AUDIO_I2S)
|
||||
#if defined(PICO_PIO_PWM_AUDIO)
|
||||
init_pio_pwm_audio();
|
||||
#elif defined(PICO_AUDIO_I2S)
|
||||
init_is2_audio();
|
||||
#elif defined(PICO_HDMI_AUDIO)
|
||||
init_hdmi_audio();
|
||||
@ -278,17 +315,24 @@ void zxSpectrumAudioInit() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void __not_in_flash_func(zxSpectrumAudioHandler)(uint32_t vA, uint32_t vB, uint32_t vC, uint32_t s, uint32_t buzzer, bool mute) {
|
||||
#if defined(PICO_HDMI_AUDIO) || defined(PICO_AUDIO_I2S)
|
||||
void __not_in_flash_func(zxSpectrumAudioHandler)(uint32_t vA, uint32_t vB, uint32_t vC, int32_t s, uint32_t buzzer, bool mute) {
|
||||
#if defined(PICO_PIO_PWM_AUDIO)
|
||||
const int32_t l = vA + vC + vB + s - (128*3);
|
||||
const int32_t v = __mul_instruction(_vol, 60);
|
||||
const int32_t lr = __mul_instruction(v, l) >> (8 + 6);
|
||||
const int32_t k = lr + 512;
|
||||
pio_pwm_set_level(PICO_AUDIO_PWM_PIO, pwm_audio_sm, k < 0 ? 0 : k > 1024 ? 1024 : k);
|
||||
#elif defined(PICO_HDMI_AUDIO) || defined(PICO_AUDIO_I2S)
|
||||
uint32_t ll, rr;
|
||||
if (mute) {
|
||||
ll = rr = 0;
|
||||
}
|
||||
else {
|
||||
uint32_t l = (((vA << 1) + vB + s) << 4) - ((255 + 255 + 255 + 255) << (4 - 1));
|
||||
uint32_t r = (((vC << 1) + vB + s) << 4) - ((255 + 255 + 255 + 255) << (4 - 1));
|
||||
ll = (__mul_instruction(_vol, l) >> 8) & 0xffff;
|
||||
rr = (__mul_instruction(_vol, r) >> 8) & 0xffff;
|
||||
const int32_t l = (vA << 1) + vB + s - (128*3);
|
||||
const int32_t r = (vC << 1) + vB + s - (128*3);
|
||||
const int32_t v = __mul_instruction(_vol, 60);
|
||||
ll = (__mul_instruction(v, l) >> 8) & 0xffff;
|
||||
rr = (__mul_instruction(v, r) >> 8) & 0xffff;
|
||||
}
|
||||
#if defined(PICO_HDMI_AUDIO)
|
||||
audio_sample_t *audio_ptr = get_write_pointer(&dvi0.audio_ring);
|
||||
@ -298,7 +342,7 @@ void __not_in_flash_func(zxSpectrumAudioHandler)(uint32_t vA, uint32_t vB, uint3
|
||||
#if defined(PICO_AUDIO_I2S)
|
||||
if (is2_audio_ready()) {
|
||||
is2_audio_put((ll << 16) | rr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#elif defined(PICO_AUDIO_I2S)
|
||||
is2_audio_put((ll << 16) | rr);
|
||||
@ -328,7 +372,10 @@ uint32_t zxSpectrumAudioGetVolume() { return _vol; }
|
||||
void zxSpectrumAudioSetVolume(uint32_t vol) { _vol = vol; }
|
||||
|
||||
bool __not_in_flash_func(zxSpectrumAudioReady)() {
|
||||
#if defined(PICO_HDMI_AUDIO)
|
||||
#if defined(PICO_PIO_PWM_AUDIO)
|
||||
return !pio_sm_is_tx_fifo_full(PICO_AUDIO_PWM_PIO, pwm_audio_sm);
|
||||
// return !(PICO_AUDIO_PWM_PIO->fstat & (1u << (pwm_audio_sm + PIO_FSTAT_TXFULL_LSB)));
|
||||
#elif defined(PICO_HDMI_AUDIO)
|
||||
return get_write_size(&dvi0.audio_ring, true) > 0;
|
||||
#elif defined(PICO_AUDIO_I2S)
|
||||
return is2_audio_ready();
|
||||
|
@ -38,7 +38,7 @@
|
||||
|
||||
void zxSpectrumAudioInit();
|
||||
|
||||
void zxSpectrumAudioHandler(uint32_t vA, uint32_t vB, uint32_t vC, uint32_t buzzerSmoothed, uint32_t buzzer, bool mute);
|
||||
void zxSpectrumAudioHandler(uint32_t vA, uint32_t vB, uint32_t vC, int32_t buzzerSmoothed, uint32_t buzzer, bool mute);
|
||||
|
||||
uint32_t zxSpectrumReadEar();
|
||||
bool zxSpectrumEarReady();
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include "BufferedInputStream.h"
|
||||
#include "hardware/clocks.h"
|
||||
#include "ff.h"
|
||||
#include "ZxSpectrumVoltage.h"
|
||||
#include "PicoCoreVoltage.h"
|
||||
|
||||
// #define DEBUG_ZX_MENU
|
||||
|
||||
@ -72,7 +74,7 @@ void ZxSpectrumMenu::setWizLayout(int32_t margin, int32_t cols1, int32_t cols2)
|
||||
_reset.move(0, 0, _wizCols, _reset.wh());
|
||||
_joystick.move(0, 0, _wizCols, _joystick.wh());
|
||||
_mouse.move(0, 0, _wizCols, _mouse.wh());
|
||||
_devices.move(0, 3, _wizCols, _devices.wh());
|
||||
_devices.move(0, 2, _wizCols, _devices.wh());
|
||||
_tzxSelect.move(0, 0, _wizCols, _tzxSelect.wh());
|
||||
repaint();
|
||||
}
|
||||
@ -98,10 +100,13 @@ ZxSpectrumMenu::ZxSpectrumMenu(
|
||||
_zxSpectrum(zxSpectrum),
|
||||
_zxSpectrumSettings(settings),
|
||||
_tis(0),
|
||||
_k1('1'), _k2('2'), _k3('3'), _k4('4'), _k5('5'), _k6('6'), _k7('7'), _k8('8'), _k9('9'), _kV('v'), _kK('k'), _kS('s'),
|
||||
|
||||
_k1('1'), _k2('2'), _k3('3'), _k4('4'), _k5('5'), _k6('6'), _k7('7'), _k8('8'), _k9('9'),
|
||||
_kV('v'), _kK('k'), _kS('s'), _kQ('q'),
|
||||
|
||||
_wiz(_wizLeftMargin, 6, _wizCols, _explorerRows * _explorerRowsPerFile),
|
||||
_wizUtils(&_wiz, _explorerRowsPerFile, &_k1, &_k2),
|
||||
_main(0, 0, _wizCols, 12, _menuRowsPerItem),
|
||||
_main(0, 0, _wizCols, 13, _menuRowsPerItem),
|
||||
|
||||
_tapePlayer(0, 0, _wizCols, 6, _menuRowsPerItem),
|
||||
|
||||
@ -135,7 +140,7 @@ ZxSpectrumMenu::ZxSpectrumMenu(
|
||||
_volume(0, 0, 16, 16),
|
||||
_keyboard(((SZ_FRAME_COLS-54)/2)-2 , 0, 52, 30),
|
||||
|
||||
_devices(0, 3, _wizCols, 1),
|
||||
_devices(0, 2, _wizCols, 2),
|
||||
|
||||
_tzxSelect(0, 0, _wizCols, 6, _menuRowsPerItem)
|
||||
{
|
||||
@ -153,7 +158,18 @@ ZxSpectrumMenu::ZxSpectrumMenu(
|
||||
bool k1 = _zxSpectrum->keyboard1() && _zxSpectrum->keyboard1()->isMounted();
|
||||
bool k2 = _zxSpectrum->keyboard2() && _zxSpectrum->keyboard2()->isMounted();
|
||||
bool m = _zxSpectrum->mouse() && _zxSpectrum->mouse()->isMounted();
|
||||
pen->printAtF(0, 0, false,"USB: Joystick%s %s%s%s, Keyboard%s %s%s%s, Mice: %s",
|
||||
const float vsys = read_voltage_sensor();
|
||||
const float vcore = pico_get_core_voltage();
|
||||
const float fmhz = (float)clock_get_hz(clk_sys) / 1000000.0;
|
||||
|
||||
pen->printAtF(0, 0, false,
|
||||
"Clk: %3.1fMhz Vcore:%1.2fv Vsys:%1.2fv",
|
||||
fmhz,
|
||||
vcore,
|
||||
vsys
|
||||
);
|
||||
|
||||
pen->printAtF(0, 1, false,"USB: Joystick%s %s%s%s, Keyboard%s %s%s%s, Mice: %s",
|
||||
(jl + jr ? "s" : ""),
|
||||
(jl ? "L" : ""), (!jl && !jr ? "0" : (!!jl & !!jr ? "&" : "")), (jr ? "R" : ""),
|
||||
(k1 == k2 ? "s" : ""),
|
||||
@ -184,7 +200,7 @@ ZxSpectrumMenu::ZxSpectrumMenu(
|
||||
#endif
|
||||
_main.addOption(_keyboardOp.addQuickKey(&_kK));
|
||||
_main.addOption(_systemOp.addQuickKey(&_kS));
|
||||
|
||||
_main.addOption(_quickSaveOp.addQuickKey(&_kQ));
|
||||
|
||||
_main.enableQuickKeys();
|
||||
_snapOp.onPaint([=](PicoPen *pen){
|
||||
@ -300,6 +316,16 @@ ZxSpectrumMenu::ZxSpectrumMenu(
|
||||
[](PicoPen *pen){ pen->printAt(0, 0, false, "System"); },
|
||||
true);
|
||||
});
|
||||
|
||||
_quickSaveOp.onPaint([=](PicoPen *pen){
|
||||
pen->clear();
|
||||
pen->printAtF(0, 0, false,"%-*s", _wizCol1Width, "Quick save");
|
||||
});
|
||||
_quickSaveOp.toggle([=]() {
|
||||
quickSave(0);
|
||||
if (_snapLoadedListener) _snapLoadedListener("QS1");
|
||||
});
|
||||
|
||||
_systemBootSelOp.toggle([=]() {
|
||||
_wizUtils.confirm(
|
||||
[=](PicoPen *pen){
|
||||
@ -519,13 +545,15 @@ ZxSpectrumMenu::ZxSpectrumMenu(
|
||||
};
|
||||
|
||||
onPaint([](PicoPen *pen) {
|
||||
#ifdef MURMULATOR
|
||||
pen->printAt(0, 0, false, "ZX Spectrum 48K/128K by fruit-bat on MURMULATOR");
|
||||
#ifdef ZX_PLATFORM
|
||||
pen->printAtF(0, 0, false, "ZX Spectrum 48K/128K by fruit-bat on %s", ZX_PLATFORM);
|
||||
#else
|
||||
pen->printAt(0, 0, false, "ZX Spectrum 48K/128K by fruit-bat");
|
||||
#endif
|
||||
pen->printAtF(0, 1, false, "on %s Pico Pi at %3.1fMhz", PICO_MCU, (float)clock_get_hz(clk_sys) / 1000000.0);
|
||||
pen->printAtF(0, 2, false, "Menu System version %d.%d", ZX_VERSION_MAJOR, ZX_VERSION_MINOR);
|
||||
pen->printAtF(0, 1, false, "Built for %s on %s",
|
||||
PICO_MCU,
|
||||
__DATE__
|
||||
);
|
||||
|
||||
pen->printAt(0, SZ_FRAME_ROWS-1, false, "F1 to exit menu");
|
||||
pen->printAt(SZ_FRAME_COLS-14, SZ_FRAME_ROWS-1, false, "ESC to go back");
|
||||
@ -639,7 +667,7 @@ void ZxSpectrumMenu::quickLoad(int slot) {
|
||||
|
||||
void ZxSpectrumMenu::initialise() {
|
||||
loadSettings();
|
||||
|
||||
|
||||
_pathQuickSaves.createFolders(_sdCard);
|
||||
_pathTapes.createFolders(_sdCard);
|
||||
|
||||
|
@ -52,6 +52,7 @@ private:
|
||||
PicoQuickKeyAscii _kV;
|
||||
PicoQuickKeyAscii _kK;
|
||||
PicoQuickKeyAscii _kS;
|
||||
PicoQuickKeyAscii _kQ;
|
||||
|
||||
PicoWiz _wiz;
|
||||
PicoWizUtils _wizUtils;
|
||||
@ -69,6 +70,7 @@ private:
|
||||
PicoOption _volumeOp;
|
||||
PicoOption _keyboardOp;
|
||||
PicoOption _systemOp;
|
||||
PicoOption _quickSaveOp;
|
||||
|
||||
PicoSelect _tapePlayer;
|
||||
PicoOptionText _chooseTapeOp;
|
||||
|
22
src/ZxSpectrumVoltage.h
Normal file
22
src/ZxSpectrumVoltage.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "hardware/gpio.h"
|
||||
#include "hardware/adc.h"
|
||||
|
||||
static bool voltage_sensor_ready = false;
|
||||
|
||||
void init_voltage_sensor() {
|
||||
adc_init();
|
||||
adc_gpio_init(29);
|
||||
adc_select_input(3);
|
||||
voltage_sensor_ready = true;
|
||||
}
|
||||
|
||||
float read_voltage_sensor() {
|
||||
if (!voltage_sensor_ready) init_voltage_sensor();
|
||||
const float conversion_factor = (3.3f * 3.0f) / (1 << 12);
|
||||
uint16_t result = adc_read();
|
||||
const float v1 = (float)result * conversion_factor;
|
||||
|
||||
return v1;
|
||||
}
|
@ -20,9 +20,14 @@ foreach(target
|
||||
${zxspectrum_hdmi_src}
|
||||
)
|
||||
|
||||
pico_generate_pio_header(${target}
|
||||
pico_generate_pio_header(${target}
|
||||
${zxspectrum_ear_in_pio}
|
||||
)
|
||||
|
||||
pico_generate_pio_header(${target}
|
||||
${zxspectrum_pwm_pio}
|
||||
)
|
||||
|
||||
endforeach()
|
||||
|
||||
add_executable(ZxSpectrumBreadboardHdmiKbd1PinAudio
|
||||
@ -32,13 +37,13 @@ add_executable(ZxSpectrumBreadboardHdmiKbd1PinAudio
|
||||
)
|
||||
|
||||
set(zxspectrum_hdmi_defines
|
||||
DVI_DEFAULT_SERIAL_CONFIG=${DVI_DEFAULT_SERIAL_CONFIG}
|
||||
DVI_DEFAULT_SERIAL_CONFIG=pico_sock_cfg
|
||||
PICO_CORE1_STACK_SIZE=0x400
|
||||
DVI_VERTICAL_REPEAT=2
|
||||
DVI_N_TMDS_BUFFERS=3
|
||||
DVI_1BPP_BIT_REVERSE=1
|
||||
# Tell FATFS we want to find files
|
||||
FF_USE_FIND=1
|
||||
FF_USE_FIND=1
|
||||
# Configure the SPI sd card to use SPI0
|
||||
SDCARD_PIN_SPI0_CS=5
|
||||
SDCARD_PIN_SPI0_SCK=2
|
||||
@ -57,6 +62,8 @@ set(zxspectrum_hdmi_640x480x60Hz_defines
|
||||
DISPLAY_HEIGHT_PIXELS=480
|
||||
# The default interrupt source
|
||||
ZX_SPECTRUM_INT_SRC=SyncToCpu
|
||||
# Speaker pin audio (@252MHz 252000000 / (1000 * 3 * 2))
|
||||
PICO_PWM_AUDIO_FREQ=42000
|
||||
)
|
||||
|
||||
set(zxspectrum_hdmi_720x540x50Hz_defines
|
||||
@ -71,6 +78,8 @@ set(zxspectrum_hdmi_720x540x50Hz_defines
|
||||
DISPLAY_HEIGHT_PIXELS=540
|
||||
# The default interrupt source
|
||||
ZX_SPECTRUM_INT_SRC=SyncToDisplay
|
||||
# Speaker pin audio (@270MHz 270000000 / (1000 * 3 * 2))
|
||||
PICO_PWM_AUDIO_FREQ=45000
|
||||
)
|
||||
|
||||
set(zxspectrum_hdmi_720x576x50Hz_defines
|
||||
@ -85,6 +94,8 @@ set(zxspectrum_hdmi_720x576x50Hz_defines
|
||||
DISPLAY_HEIGHT_PIXELS=576
|
||||
# The default interrupt source
|
||||
ZX_SPECTRUM_INT_SRC=SyncToDisplay
|
||||
# Speaker pin audio (@270MHz 270000000 / (1000 * 3 * 2))
|
||||
PICO_PWM_AUDIO_FREQ=45000
|
||||
)
|
||||
|
||||
set(zxspectrum_hdmi_nespad_defines
|
||||
@ -101,7 +112,7 @@ target_compile_definitions(ZxSpectrumBreadboardHdmiAudio PRIVATE
|
||||
${zxspectrum_hdmi_640x480x60Hz_defines}
|
||||
${zxspectrum_hdmi_nespad_defines}
|
||||
EAR_PIN=11
|
||||
PICO_HDMI_AUDIO
|
||||
PICO_HDMI_AUDIO
|
||||
# Enable the PS/2 keyboard
|
||||
USE_PS2_KBD
|
||||
)
|
||||
@ -111,7 +122,7 @@ target_compile_definitions(ZxSpectrumBreadboardHdmiAudio720x540x50Hz PRIVATE
|
||||
${zxspectrum_hdmi_720x540x50Hz_defines}
|
||||
${zxspectrum_hdmi_nespad_defines}
|
||||
EAR_PIN=11
|
||||
PICO_HDMI_AUDIO
|
||||
PICO_HDMI_AUDIO
|
||||
# Enable the PS/2 keyboard
|
||||
USE_PS2_KBD
|
||||
)
|
||||
@ -119,9 +130,9 @@ target_compile_definitions(ZxSpectrumBreadboardHdmiAudio720x540x50Hz PRIVATE
|
||||
target_compile_definitions(ZxSpectrumBreadboardHdmiAudio720x576x50Hz PRIVATE
|
||||
${zxspectrum_hdmi_defines}
|
||||
${zxspectrum_hdmi_720x576x50Hz_defines}
|
||||
${zxspectrum_hdmi_nespad_defines}
|
||||
EAR_PIN=11
|
||||
PICO_HDMI_AUDIO
|
||||
# ${zxspectrum_hdmi_nespad_defines}
|
||||
# EAR_PIN=11
|
||||
PICO_HDMI_AUDIO
|
||||
# Enable the PS/2 keyboard
|
||||
USE_PS2_KBD
|
||||
)
|
||||
@ -167,7 +178,7 @@ target_compile_definitions(ZxSpectrumBreadboardHdmiKbd1PinAudio PRIVATE
|
||||
PCS_COLS=80
|
||||
PCS_ROWS=30
|
||||
# Tell FATFS we want to find files
|
||||
FF_USE_FIND=1
|
||||
FF_USE_FIND=1
|
||||
# Single pin audio for now
|
||||
SPK_PIN=20
|
||||
# 21 is also free
|
||||
@ -177,7 +188,7 @@ target_compile_definitions(ZxSpectrumBreadboardHdmiKbd1PinAudio PRIVATE
|
||||
SDCARD_PIN_SPI0_CS=28
|
||||
SDCARD_PIN_SPI0_SCK=22
|
||||
SDCARD_PIN_SPI0_MOSI=26
|
||||
SDCARD_PIN_SPI0_MISO=27
|
||||
SDCARD_PIN_SPI0_MISO=27
|
||||
USE_KEY_MATRIX
|
||||
)
|
||||
|
||||
@ -233,7 +244,7 @@ set (zxspectrum_pico_dv_defines
|
||||
)
|
||||
|
||||
set (zxspectrum_pico_dv_i2saudio_defines
|
||||
# Configure the I2S audio
|
||||
# Configure the I2S audio
|
||||
PICO_AUDIO_I2S=1
|
||||
PICO_AUDIO_I2S_PIO=pio1
|
||||
PICO_AUDIO_I2S_PIO_FUNC=GPIO_FUNC_PIO1
|
||||
@ -252,11 +263,11 @@ foreach(target
|
||||
${zxspectrum_hdmi_src}
|
||||
)
|
||||
|
||||
pico_generate_pio_header(${target}
|
||||
pico_generate_pio_header(${target}
|
||||
${zxspectrum_audio_i2s_pio}
|
||||
)
|
||||
|
||||
target_link_libraries(${target}
|
||||
target_link_libraries(${target}
|
||||
${zxspectrum_common_libs}
|
||||
${zxspectrum_hdmi_libs}
|
||||
)
|
||||
@ -294,7 +305,7 @@ target_compile_definitions(ZxSpectrumPicoDv_HdmiAudio_720x576x50Hz PRIVATE
|
||||
########################################################################
|
||||
|
||||
# cmake -DPICO_COPY_TO_RAM=0 -DPICO_SDK_PATH=../../pico-sdk -DPICO_BOARD=adafruit_feather_rp2040 ..
|
||||
# make -j4 ZxSpectrumAdafruitFeatherHdmi
|
||||
# make -j4 ZxSpectrumAdafruitFeatherHdmi
|
||||
foreach(target
|
||||
ZxSpectrumAdafruitFeatherHdmi
|
||||
)
|
||||
@ -320,16 +331,17 @@ set(zx_spectrum_adafuit_feather_hdmi_defines
|
||||
DVI_N_TMDS_BUFFERS=3
|
||||
DVI_1BPP_BIT_REVERSE=1
|
||||
# Tell FATFS we want to find files
|
||||
FF_USE_FIND=1
|
||||
FF_USE_FIND=1
|
||||
# Configure the SPI sd card to use SPI0
|
||||
SDCARD_PIO=pio1
|
||||
SDCARD_PIO_SM=1
|
||||
SDCARD_PIO_SM=1
|
||||
SDCARD_PIN_SPI0_CS=13
|
||||
SDCARD_PIN_SPI0_SCK=10
|
||||
SDCARD_PIN_SPI0_MOSI=11
|
||||
SDCARD_PIN_SPI0_MISO=12
|
||||
# Speaker pin audio
|
||||
SPK_PIN=25
|
||||
|
||||
PICO_HDMI_AUDIO
|
||||
|
||||
# defines from the board type
|
||||
# PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H=1
|
||||
|
||||
@ -348,7 +360,7 @@ target_compile_definitions(ZxSpectrumAdafruitFeatherHdmi PRIVATE
|
||||
# Waveshare - RP2040 - PicoZero
|
||||
########################################################################
|
||||
|
||||
foreach(target
|
||||
foreach(target
|
||||
ZxSpectrumPiZero_640x480x60Hz
|
||||
ZxSpectrumPiZero_720x576x50Hz
|
||||
)
|
||||
@ -384,7 +396,7 @@ set (ZxSpectrumPiZero_defines
|
||||
SDCARD_PIN_SPI0_SCK=18
|
||||
SDCARD_PIN_SPI0_MOSI=19
|
||||
SDCARD_PIN_SPI0_MISO=20
|
||||
# HDMI audio
|
||||
# HDMI audio
|
||||
PICO_HDMI_AUDIO
|
||||
)
|
||||
|
||||
@ -405,7 +417,6 @@ target_compile_definitions(ZxSpectrumPiZero_720x576x50Hz PRIVATE
|
||||
set(zxspectrum_murmulator_src
|
||||
main.cpp
|
||||
${zxspectrum_dvi_src}
|
||||
${murmulator_common_src}
|
||||
)
|
||||
|
||||
set(zxspectrum_murmulator_hdmi_nespad_defines
|
||||
@ -418,8 +429,8 @@ set(zxspectrum_murmulator_hdmi_nespad_defines
|
||||
)
|
||||
|
||||
set(murmulator_common_defines
|
||||
ZX_PLATFORM="MURMULATOR"
|
||||
# Set up the DVI output to match the MURMULATOR board
|
||||
MURMULATOR
|
||||
PICO_CORE1_STACK_SIZE=0x400
|
||||
DVI_DEFAULT_SERIAL_CONFIG=pimoroni_demo_hdmi_cfg
|
||||
DVI_VERTICAL_REPEAT=2
|
||||
@ -435,12 +446,12 @@ set(murmulator_common_defines
|
||||
SDCARD_PIN_SPI0_MOSI=3
|
||||
SDCARD_PIN_SPI0_MISO=4
|
||||
# Use the alternate volume map
|
||||
AY8912_ALT_VOL_MAP
|
||||
AY8912_ALT_VOL_MAP
|
||||
# Tape audio in
|
||||
EAR_PIN=22
|
||||
# Enable the PS/2 keyboard
|
||||
USE_PS2_KBD
|
||||
USE_MRMLTR_PS2_KBD
|
||||
PS2KBD_CLK0_DAT
|
||||
)
|
||||
|
||||
set(murmulator_pwm_audio_defines
|
||||
@ -461,7 +472,7 @@ set(murmulator_hdmi_audio_defines
|
||||
PICO_HDMI_AUDIO
|
||||
)
|
||||
|
||||
foreach(target
|
||||
foreach(target
|
||||
ZX-MURMULATOR_HDMI_PWM_AUDIO_640x480x60Hz
|
||||
ZX-MURMULATOR_HDMI_PWM_AUDIO_720x576x50Hz
|
||||
ZX-MURMULATOR_HDMI_HDMI_AUDIO_640x480x60Hz
|
||||
@ -484,16 +495,16 @@ foreach(target
|
||||
)
|
||||
|
||||
pico_generate_pio_header(${target}
|
||||
${murmulator_ps2kbd_pio}
|
||||
)
|
||||
|
||||
pico_generate_pio_header(${target}
|
||||
${zxspectrum_audio_i2s_pio}
|
||||
)
|
||||
|
||||
pico_generate_pio_header(${target}
|
||||
${zxspectrum_pwm_pio}
|
||||
)
|
||||
|
||||
# create map/bin/hex file etc.
|
||||
pico_add_extra_outputs(${target})
|
||||
|
||||
pico_add_extra_outputs(${target})
|
||||
|
||||
endforeach()
|
||||
|
||||
target_compile_definitions(ZX-MURMULATOR_HDMI_HDMI_AUDIO_640x480x60Hz PRIVATE
|
||||
@ -508,7 +519,6 @@ target_compile_definitions(ZX-MURMULATOR_HDMI_HDMI_AUDIO_720x576x50Hz PRIVATE
|
||||
${murmulator_hdmi_audio_defines}
|
||||
${zxspectrum_hdmi_720x576x50Hz_defines}
|
||||
${zxspectrum_murmulator_hdmi_nespad_defines}
|
||||
|
||||
)
|
||||
|
||||
target_compile_definitions(ZX-MURMULATOR_HDMI_PWM_AUDIO_640x480x60Hz PRIVATE
|
||||
@ -539,6 +549,152 @@ target_compile_definitions(ZX-MURMULATOR_HDMI_I2S_AUDIO_720x576x50Hz PRIVATE
|
||||
${zxspectrum_murmulator_hdmi_nespad_defines}
|
||||
)
|
||||
|
||||
########################################################################
|
||||
# ZX-MURMULATOR2
|
||||
########################################################################
|
||||
|
||||
set(zxspectrum_murmulator2_src
|
||||
main.cpp
|
||||
${zxspectrum_dvi_src}
|
||||
)
|
||||
|
||||
set(zxspectrum_murmulator2_hdmi_nespad_defines
|
||||
# Pins for dual NES joypads
|
||||
NESPAD_DATA_PIN_BASE=26
|
||||
NESPAD_CLK_PIN_BASE=20
|
||||
NESPAD_PIO=pio1
|
||||
NESPAD_IRQ=PIO1_IRQ_0
|
||||
NESPAD_ENABLE
|
||||
)
|
||||
|
||||
set(murmulator2_common_defines
|
||||
ZX_PLATFORM="MURMULATOR2"
|
||||
# Set up the DVI output to match the MURMULATOR board
|
||||
DVI_CUSTOM_CONFIG
|
||||
DVI_DEFAULT_SERIAL_CONFIG=murmulator2_hdmi_cfg
|
||||
PICO_CORE1_STACK_SIZE=0x400
|
||||
DVI_VERTICAL_REPEAT=2
|
||||
DVI_N_TMDS_BUFFERS=3
|
||||
DVI_1BPP_BIT_REVERSE=1
|
||||
# Tell FATFS we want to find files
|
||||
FF_USE_FIND=1
|
||||
# Configure the SPI sd card to use PIO
|
||||
SDCARD_PIN_SPI0_CS=5
|
||||
SDCARD_PIN_SPI0_SCK=6
|
||||
SDCARD_PIN_SPI0_MOSI=7
|
||||
SDCARD_PIN_SPI0_MISO=4
|
||||
# Use the alternate volume map
|
||||
AY8912_ALT_VOL_MAP
|
||||
# Tape audio in
|
||||
EAR_PIN=22
|
||||
# Enable the PS/2 keyboard
|
||||
USE_PS2_KBD
|
||||
PS2KBD_CLK2_DAT
|
||||
)
|
||||
|
||||
set(murmulator2_pwm_audio_defines
|
||||
#
|
||||
# This could be ABC output on GPIO 10, 9, 11 but the sofware FIFO is not working on the RP2350
|
||||
# For now I will output mono PWM using a PIO block on GPIO 10
|
||||
#
|
||||
PICO_AUDIO_PWM_PIO=pio1
|
||||
PICO_PIO_PWM_AUDIO
|
||||
SPK_PIN=9
|
||||
)
|
||||
|
||||
set (zxspectrum_murmulator2_i2saudio_defines
|
||||
# Configure the I2S audio
|
||||
PICO_AUDIO_I2S=1
|
||||
PICO_AUDIO_I2S_PIO=pio1
|
||||
PICO_AUDIO_I2S_PIO_FUNC=GPIO_FUNC_PIO1
|
||||
PICO_AUDIO_I2S_DATA=9
|
||||
PICO_AUDIO_I2S_BCLK=10
|
||||
)
|
||||
|
||||
set(murmulator2_hdmi_audio_defines
|
||||
# Use HDMI Audio
|
||||
PICO_HDMI_AUDIO
|
||||
)
|
||||
|
||||
foreach(target
|
||||
ZX-MURMULATOR2_HDMI_PWM_AUDIO_640x480x60Hz
|
||||
ZX-MURMULATOR2_HDMI_PWM_AUDIO_720x576x50Hz
|
||||
ZX-MURMULATOR2_HDMI_HDMI_AUDIO_640x480x60Hz
|
||||
ZX-MURMULATOR2_HDMI_HDMI_AUDIO_720x576x50Hz
|
||||
ZX-MURMULATOR2_HDMI_I2S_AUDIO_640x480x60Hz
|
||||
ZX-MURMULATOR2_HDMI_I2S_AUDIO_720x576x50Hz
|
||||
)
|
||||
add_executable(${target}
|
||||
${zxspectrum_common_src}
|
||||
${zxspectrum_murmulator2_src}
|
||||
)
|
||||
|
||||
target_link_libraries(${target}
|
||||
${zxspectrum_common_libs}
|
||||
${zxspectrum_hdmi_libs}
|
||||
)
|
||||
|
||||
pico_generate_pio_header(${target}
|
||||
${zxspectrum_ear_in_pio}
|
||||
)
|
||||
|
||||
pico_generate_pio_header(${target}
|
||||
${zxspectrum_audio_i2s_pio}
|
||||
)
|
||||
|
||||
pico_generate_pio_header(${target}
|
||||
${zxspectrum_pwm_pio}
|
||||
)
|
||||
|
||||
# create map/bin/hex file etc.
|
||||
pico_add_extra_outputs(${target})
|
||||
|
||||
pico_enable_stdio_usb(${target} 0)
|
||||
pico_enable_stdio_uart(${target} 1)
|
||||
|
||||
endforeach()
|
||||
|
||||
target_compile_definitions(ZX-MURMULATOR2_HDMI_HDMI_AUDIO_640x480x60Hz PRIVATE
|
||||
${murmulator2_common_defines}
|
||||
${murmulator2_hdmi_audio_defines}
|
||||
${zxspectrum_hdmi_640x480x60Hz_defines}
|
||||
${zxspectrum_murmulator2_hdmi_nespad_defines}
|
||||
)
|
||||
|
||||
target_compile_definitions(ZX-MURMULATOR2_HDMI_HDMI_AUDIO_720x576x50Hz PRIVATE
|
||||
${murmulator2_common_defines}
|
||||
${murmulator2_hdmi_audio_defines}
|
||||
${zxspectrum_hdmi_720x576x50Hz_defines}
|
||||
${zxspectrum_murmulator2_hdmi_nespad_defines}
|
||||
)
|
||||
|
||||
target_compile_definitions(ZX-MURMULATOR2_HDMI_PWM_AUDIO_640x480x60Hz PRIVATE
|
||||
${murmulator2_common_defines}
|
||||
${murmulator2_pwm_audio_defines}
|
||||
${zxspectrum_hdmi_640x480x60Hz_defines}
|
||||
${zxspectrum_murmulator2_hdmi_nespad_defines}
|
||||
)
|
||||
|
||||
target_compile_definitions(ZX-MURMULATOR2_HDMI_PWM_AUDIO_720x576x50Hz PRIVATE
|
||||
${murmulator2_common_defines}
|
||||
${murmulator2_pwm_audio_defines}
|
||||
${zxspectrum_hdmi_720x576x50Hz_defines}
|
||||
${zxspectrum_murmulator2_hdmi_nespad_defines}
|
||||
)
|
||||
|
||||
target_compile_definitions(ZX-MURMULATOR2_HDMI_I2S_AUDIO_640x480x60Hz PRIVATE
|
||||
${murmulator2_common_defines}
|
||||
${zxspectrum_murmulator2_i2saudio_defines}
|
||||
${zxspectrum_hdmi2_640x480x60Hz_defines}
|
||||
${zxspectrum_murmulator2_hdmi_nespad_defines}
|
||||
)
|
||||
|
||||
target_compile_definitions(ZX-MURMULATOR2_HDMI_I2S_AUDIO_720x576x50Hz PRIVATE
|
||||
${murmulator2_common_defines}
|
||||
${zxspectrum_murmulator2_i2saudio_defines}
|
||||
${zxspectrum_hdmi_720x576x50Hz_defines}
|
||||
${zxspectrum_murmulator2_hdmi_nespad_defines}
|
||||
)
|
||||
|
||||
########################################################################
|
||||
# Olimex RP2040-PICO-PC
|
||||
@ -572,7 +728,7 @@ set(olimex_pc_hdmi_audio_defines
|
||||
PICO_HDMI_AUDIO
|
||||
)
|
||||
|
||||
foreach(target
|
||||
foreach(target
|
||||
ZxSpectrumOlimexPcHdmiAudio640x480x60Hz
|
||||
ZxSpectrumOlimexPcHdmiAudio720x576x50Hz
|
||||
)
|
||||
@ -587,8 +743,8 @@ foreach(target
|
||||
)
|
||||
|
||||
# create map/bin/hex file etc.
|
||||
pico_add_extra_outputs(${target})
|
||||
|
||||
pico_add_extra_outputs(${target})
|
||||
|
||||
pico_enable_stdio_usb(${target} 0)
|
||||
pico_enable_stdio_uart(${target} 1)
|
||||
|
||||
|
@ -26,4 +26,12 @@ static const struct dvi_serialiser_cfg waveshare_rp2040_pizero_hdmi_cfg = {
|
||||
.invert_diffpairs = false
|
||||
};
|
||||
|
||||
static const struct dvi_serialiser_cfg murmulator2_hdmi_cfg = {
|
||||
.pio = DVI_DEFAULT_PIO_INST,
|
||||
.sm_tmds = {0, 1, 2},
|
||||
.pins_tmds = {14, 16, 18},
|
||||
.pins_clk = 12,
|
||||
.invert_diffpairs = true
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "hardware/irq.h"
|
||||
#include "hardware/sync.h"
|
||||
#include "hardware/gpio.h"
|
||||
#include "hardware/vreg.h"
|
||||
#include "PicoCoreVoltage.h"
|
||||
#include "hardware/structs/bus_ctrl.h"
|
||||
#include "hardware/dma.h"
|
||||
#include "hardware/uart.h"
|
||||
@ -14,9 +14,7 @@
|
||||
#include "hardware/pwm.h"
|
||||
#include "hid_app.h"
|
||||
|
||||
#ifdef USE_MRMLTR_PS2_KBD
|
||||
#include "ps2kbd_mrmltr.h"
|
||||
#elif defined(USE_PS2_KBD)
|
||||
#if defined(USE_PS2_KBD)
|
||||
#include "ps2kbd.h"
|
||||
#endif
|
||||
|
||||
@ -230,16 +228,10 @@ void __not_in_flash_func(process_joystick)() {
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_MRMLTR_PS2_KBD
|
||||
static Ps2Kbd_Mrmltr ps2kbd(
|
||||
pio1,
|
||||
0,
|
||||
process_kbd_report
|
||||
);
|
||||
#elif defined(USE_PS2_KBD)
|
||||
#if defined(USE_PS2_KBD)
|
||||
static Ps2Kbd ps2kbd(
|
||||
pio1,
|
||||
6,
|
||||
PS2KBD_GPIO, // Was 6
|
||||
process_kbd_report
|
||||
);
|
||||
#endif
|
||||
@ -365,8 +357,7 @@ void __not_in_flash_func(main_loop)() {
|
||||
}
|
||||
|
||||
int main() {
|
||||
vreg_set_voltage(VREG_VSEL);
|
||||
sleep_ms(10);
|
||||
pico_set_core_voltage();
|
||||
|
||||
// Run system at TMDS bit clock
|
||||
set_sys_clock_khz(DVI_TIMING.bit_clk_khz, true);
|
||||
|
@ -122,6 +122,8 @@ set(zxspectrum_zx_lcd_640x480x60Hz_defines
|
||||
ZX_SPECTRUM_INT_SRC=SyncToCpu
|
||||
# TODO work what this is
|
||||
PICO_SCANVIDEO_MAX_SCANLINE_BUFFER_WORDS=700
|
||||
# Speaker pin audio (@250MHz 250000000 / (1000 * 3 * 2))
|
||||
PICO_PWM_AUDIO_FREQ=41666
|
||||
)
|
||||
|
||||
set(zxspectrum_zx_lcd_720x576x50Hz_defines
|
||||
@ -138,10 +140,14 @@ set(zxspectrum_zx_lcd_720x576x50Hz_defines
|
||||
ZX_SPECTRUM_INT_SRC=SyncToDisplay
|
||||
# TODO work what this is
|
||||
PICO_SCANVIDEO_MAX_SCANLINE_BUFFER_WORDS=800
|
||||
# Speaker pin audio (@270MHz 270000000 / (1000 * 3 * 2))
|
||||
PICO_PWM_AUDIO_FREQ=45000
|
||||
)
|
||||
|
||||
set(picomputer_zx_lcd_common_defines PRIVATE
|
||||
${picomputer_common_defines}
|
||||
PICO_PIO_PWM_AUDIO
|
||||
PICO_AUDIO_PWM_PIO=pio1
|
||||
SPK_PIN=7
|
||||
PICOMPUTER_PICOZX
|
||||
PICOMPUTER_PICOZX_LCD
|
||||
@ -172,6 +178,7 @@ set(zxspectrum_zx_lcd_common_libs
|
||||
tinyusb_board
|
||||
hardware_pio
|
||||
hardware_pwm
|
||||
hardware_adc
|
||||
)
|
||||
|
||||
foreach(target
|
||||
@ -190,6 +197,10 @@ foreach(target
|
||||
${CMAKE_CURRENT_LIST_DIR}/st7789_lcd.pio
|
||||
)
|
||||
|
||||
pico_generate_pio_header(${target}
|
||||
${zxspectrum_pwm_pio}
|
||||
)
|
||||
|
||||
target_link_libraries(${target}
|
||||
${zxspectrum_zx_lcd_common_libs}
|
||||
)
|
||||
@ -241,3 +252,4 @@ target_compile_definitions(ZxSpectrumPicomputerZxILI9341Lcd_640x480x60Hz PRIVATE
|
||||
LCD_INVERSE
|
||||
LCD_RGB
|
||||
)
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include "pico/stdlib.h"
|
||||
#include "pico/multicore.h"
|
||||
#include "hardware/clocks.h"
|
||||
#include "hardware/vreg.h"
|
||||
#include "PicoCoreVoltage.h"
|
||||
#include "hardware/pwm.h"
|
||||
#include "ZxSpectrumPrepareRgbScanline.h"
|
||||
#include "pzx_prepare_rgb444_scanline.h"
|
||||
@ -346,8 +346,8 @@ void __not_in_flash_func(main_loop)() {
|
||||
}
|
||||
|
||||
int main() {
|
||||
vreg_set_voltage(VREG_VSEL);
|
||||
sleep_ms(10);
|
||||
pico_set_core_voltage();
|
||||
|
||||
#ifdef PICOMPUTER_PICOZX_LCD
|
||||
ZxScanlineVgaRenderLoopInit();
|
||||
#else
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include "pico/stdlib.h"
|
||||
#include "pico/multicore.h"
|
||||
#include "hardware/vreg.h"
|
||||
#include "PicoCoreVoltage.h"
|
||||
#include "hardware/pwm.h"
|
||||
|
||||
#include "pzx_keyscan.h"
|
||||
@ -244,8 +244,7 @@ void __not_in_flash_func(main_loop)(){
|
||||
}
|
||||
|
||||
int main(){
|
||||
vreg_set_voltage(VREG_VSEL);
|
||||
sleep_ms(10);
|
||||
pico_set_core_voltage();
|
||||
|
||||
ZxScanlineVgaRenderLoopInit();
|
||||
|
||||
|
@ -16,6 +16,8 @@ set(ZxSpectrumPicomputerVgaZx_640x480x60Hz_defines
|
||||
ZX_SPECTRUM_INT_SRC=SyncToCpu
|
||||
# TODO work what this is
|
||||
PICO_SCANVIDEO_MAX_SCANLINE_BUFFER_WORDS=700
|
||||
# Speaker pin audio (@250MHz 250000000 / (1000 * 3 * 2))
|
||||
PICO_PWM_AUDIO_FREQ=41666
|
||||
)
|
||||
|
||||
set(ZxSpectrumPicomputerVgaZx_720x576x50Hz_defines
|
||||
@ -32,6 +34,8 @@ set(ZxSpectrumPicomputerVgaZx_720x576x50Hz_defines
|
||||
ZX_SPECTRUM_INT_SRC=SyncToDisplay
|
||||
# TODO work what this is
|
||||
PICO_SCANVIDEO_MAX_SCANLINE_BUFFER_WORDS=800
|
||||
# Speaker pin audio (@270MHz 270000000 / (1000 * 3 * 2))
|
||||
PICO_PWM_AUDIO_FREQ=45000
|
||||
)
|
||||
|
||||
foreach(target
|
||||
@ -71,6 +75,9 @@ foreach(target
|
||||
# create map/bin/hex file etc.
|
||||
pico_add_extra_outputs(${target})
|
||||
|
||||
pico_generate_pio_header(${target}
|
||||
${zxspectrum_pwm_pio}
|
||||
)
|
||||
|
||||
endforeach()
|
||||
|
||||
@ -85,6 +92,8 @@ set(ZxSpectrumPicomputerVga1111Zx_defines
|
||||
PICO_SCANVIDEO_DPI_PIXEL_GSHIFT=1u
|
||||
PICO_SCANVIDEO_DPI_PIXEL_BSHIFT=0u
|
||||
PICO_SCANVIDEO_COLOR_PIN_BASE=0u
|
||||
PICO_AUDIO_PWM_PIO=pio1
|
||||
PICO_PIO_PWM_AUDIO
|
||||
SPK_PIN=9
|
||||
PICOMPUTER_VGA
|
||||
)
|
||||
@ -111,6 +120,8 @@ set(ZxSpectrumPicomputerVga222Zx_defines
|
||||
PICO_SCANVIDEO_DPI_PIXEL_GSHIFT=2u
|
||||
PICO_SCANVIDEO_DPI_PIXEL_BSHIFT=0u
|
||||
PICO_SCANVIDEO_COLOR_PIN_BASE=0u
|
||||
PICO_AUDIO_PWM_PIO=pio1
|
||||
PICO_PIO_PWM_AUDIO
|
||||
SPK_PIN=7
|
||||
PICOMPUTER_PICOZX
|
||||
)
|
||||
@ -161,6 +172,8 @@ set(ZxSpectrumPicomputerVgaAuk_defines
|
||||
PICO_SCANVIDEO_DPI_PIXEL_GSHIFT=2u
|
||||
PICO_SCANVIDEO_DPI_PIXEL_BSHIFT=0u
|
||||
PICO_SCANVIDEO_COLOR_PIN_BASE=0u
|
||||
PICO_AUDIO_PWM_PIO=pio1
|
||||
PICO_PIO_PWM_AUDIO
|
||||
SPK_PIN=7
|
||||
PICOMPUTER_PICOZX
|
||||
REAL_ZXKEYBOARD
|
||||
@ -190,6 +203,8 @@ set(ZxSpectrumPicomputerVgaAukBob_defines
|
||||
PICO_SCANVIDEO_DPI_PIXEL_GSHIFT=2u
|
||||
PICO_SCANVIDEO_DPI_PIXEL_BSHIFT=0u
|
||||
PICO_SCANVIDEO_COLOR_PIN_BASE=0u
|
||||
PICO_AUDIO_PWM_PIO=pio1
|
||||
PICO_PIO_PWM_AUDIO
|
||||
SPK_PIN=7
|
||||
PICOMPUTER_PICOZX
|
||||
REAL_ZXKEYBOARD
|
||||
@ -221,6 +236,8 @@ set(ZxSpectrumPicomputerVga1111AukBob_defines
|
||||
PICO_SCANVIDEO_DPI_PIXEL_GSHIFT=1u
|
||||
PICO_SCANVIDEO_DPI_PIXEL_BSHIFT=0u
|
||||
PICO_SCANVIDEO_COLOR_PIN_BASE=0u
|
||||
PICO_AUDIO_PWM_PIO=pio1
|
||||
PICO_PIO_PWM_AUDIO
|
||||
SPK_PIN=7
|
||||
EAR_PIN=6
|
||||
PICOMPUTER_PICOZX
|
||||
@ -229,7 +246,7 @@ set(ZxSpectrumPicomputerVga1111AukBob_defines
|
||||
HID_KEY_MOD_SAVE=2
|
||||
)
|
||||
|
||||
pico_generate_pio_header(ZxSpectrumPicomputerVga1111AukBob_720x576x50Hz
|
||||
pico_generate_pio_header(ZxSpectrumPicomputerVga1111AukBob_720x576x50Hz
|
||||
${zxspectrum_ear_in_pio}
|
||||
)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include "pico/stdlib.h"
|
||||
#include "pico/multicore.h"
|
||||
#include "hardware/vreg.h"
|
||||
#include "PicoCoreVoltage.h"
|
||||
#include "hardware/pwm.h"
|
||||
|
||||
#include "pzx_keyscan.h"
|
||||
@ -245,8 +245,7 @@ void __not_in_flash_func(main_loop)(){
|
||||
}
|
||||
|
||||
int main(){
|
||||
vreg_set_voltage(VREG_VSEL);
|
||||
sleep_ms(10);
|
||||
pico_set_core_voltage();
|
||||
|
||||
ZxScanlineVgaRenderLoopInit();
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include "pico/stdlib.h"
|
||||
#include "pico/multicore.h"
|
||||
#include "hardware/vreg.h"
|
||||
#include "PicoCoreVoltage.h"
|
||||
#include "hardware/pwm.h"
|
||||
#include "hardware/clocks.h"
|
||||
|
||||
@ -174,7 +174,7 @@ void __not_in_flash_func(process_joystick)() {
|
||||
#ifdef USE_PS2_KBD
|
||||
static Ps2Kbd ps2kbd(
|
||||
pio1,
|
||||
6,
|
||||
PS2KBD_GPIO,
|
||||
process_kbd_report
|
||||
);
|
||||
#endif
|
||||
@ -243,8 +243,8 @@ void __not_in_flash_func(main_loop)(){
|
||||
}
|
||||
|
||||
int main(){
|
||||
vreg_set_voltage(VREG_VSEL);
|
||||
sleep_ms(10);
|
||||
pico_set_core_voltage();
|
||||
|
||||
// Init 16 bit VGA
|
||||
ZxScanlineVgaRenderLoopInit();
|
||||
|
||||
|
@ -1,403 +0,0 @@
|
||||
// You may use, distribute and modify this code under the
|
||||
// terms of the GPLv2 license, which unfortunately won't be
|
||||
// written for another century.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
//
|
||||
// See:
|
||||
// http://www.vetra.com/scancodes.html
|
||||
// https://wiki.osdev.org/PS/2_Keyboard
|
||||
//
|
||||
#include "ps2kbd_mrmltr.h"
|
||||
#include "ps2kbd_mrmltr.pio.h"
|
||||
#include "hardware/clocks.h"
|
||||
|
||||
#ifdef DEBUG_PS2
|
||||
#define DBG_PRINTF(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define DBG_PRINTF(...)
|
||||
#endif
|
||||
|
||||
#define HID_KEYBOARD_REPORT_MAX_KEYS 6
|
||||
|
||||
// PS/2 set 2 to HID key conversion
|
||||
static uint8_t ps2kbd_page_0[] {
|
||||
/* 00 ( 0) */ HID_KEY_NONE,
|
||||
/* 01 ( 1) */ HID_KEY_F9,
|
||||
/* 02 ( 2) */ 0x00,
|
||||
/* 03 ( 3) */ HID_KEY_F5,
|
||||
/* 04 ( 4) */ HID_KEY_F3,
|
||||
/* 05 ( 5) */ HID_KEY_F1,
|
||||
/* 06 ( 6) */ HID_KEY_F2,
|
||||
/* 07 ( 7) */ HID_KEY_F12,
|
||||
/* 08 ( 8) */ HID_KEY_F13,
|
||||
/* 09 ( 9) */ HID_KEY_F10,
|
||||
/* 0A ( 10) */ HID_KEY_F8,
|
||||
/* 0B ( 11) */ HID_KEY_F6,
|
||||
/* 0C ( 12) */ HID_KEY_F4,
|
||||
/* 0D ( 13) */ HID_KEY_TAB,
|
||||
/* 0E ( 14) */ HID_KEY_GRAVE,
|
||||
/* 0F ( 15) */ HID_KEY_KEYPAD_EQUAL,
|
||||
/* 10 ( 16) */ HID_KEY_F14,
|
||||
/* 11 ( 17) */ HID_KEY_ALT_LEFT,
|
||||
/* 12 ( 18) */ HID_KEY_SHIFT_LEFT,
|
||||
/* 13 ( 19) */ 0x00,
|
||||
/* 14 ( 20) */ HID_KEY_CONTROL_LEFT,
|
||||
/* 15 ( 21) */ HID_KEY_Q,
|
||||
/* 16 ( 22) */ HID_KEY_1,
|
||||
/* 17 ( 23) */ 0x00,
|
||||
/* 18 ( 24) */ HID_KEY_F15,
|
||||
/* 19 ( 25) */ 0x00,
|
||||
/* 1A ( 26) */ HID_KEY_Z,
|
||||
/* 1B ( 27) */ HID_KEY_S,
|
||||
/* 1C ( 28) */ HID_KEY_A,
|
||||
/* 1D ( 29) */ HID_KEY_W,
|
||||
/* 1E ( 30) */ HID_KEY_2,
|
||||
/* 1F ( 31) */ 0x00,
|
||||
/* 20 ( 32) */ HID_KEY_F16,
|
||||
/* 21 ( 33) */ HID_KEY_C,
|
||||
/* 22 ( 34) */ HID_KEY_X,
|
||||
/* 23 ( 35) */ HID_KEY_D,
|
||||
/* 24 ( 36) */ HID_KEY_E,
|
||||
/* 25 ( 37) */ HID_KEY_4,
|
||||
/* 26 ( 38) */ HID_KEY_3,
|
||||
/* 27 ( 39) */ 0x00,
|
||||
/* 28 ( 40) */ HID_KEY_F17,
|
||||
/* 29 ( 41) */ HID_KEY_SPACE,
|
||||
/* 2A ( 42) */ HID_KEY_V,
|
||||
/* 2B ( 43) */ HID_KEY_F,
|
||||
/* 2C ( 44) */ HID_KEY_T,
|
||||
/* 2D ( 45) */ HID_KEY_R,
|
||||
/* 2E ( 46) */ HID_KEY_5,
|
||||
/* 2F ( 47) */ 0x00,
|
||||
/* 30 ( 48) */ HID_KEY_F18,
|
||||
/* 31 ( 49) */ HID_KEY_N,
|
||||
/* 32 ( 50) */ HID_KEY_B,
|
||||
/* 33 ( 51) */ HID_KEY_H,
|
||||
/* 34 ( 52) */ HID_KEY_G,
|
||||
/* 35 ( 53) */ HID_KEY_Y,
|
||||
/* 36 ( 54) */ HID_KEY_6,
|
||||
/* 37 ( 55) */ 0x00,
|
||||
/* 38 ( 56) */ HID_KEY_F19,
|
||||
/* 39 ( 57) */ 0x00,
|
||||
/* 3A ( 58) */ HID_KEY_M,
|
||||
/* 3B ( 59) */ HID_KEY_J,
|
||||
/* 3C ( 60) */ HID_KEY_U,
|
||||
/* 3D ( 61) */ HID_KEY_7,
|
||||
/* 3E ( 62) */ HID_KEY_8,
|
||||
/* 3F ( 63) */ 0x00,
|
||||
/* 40 ( 64) */ HID_KEY_F20,
|
||||
/* 41 ( 65) */ HID_KEY_COMMA,
|
||||
/* 42 ( 66) */ HID_KEY_K,
|
||||
/* 43 ( 67) */ HID_KEY_I,
|
||||
/* 44 ( 68) */ HID_KEY_O,
|
||||
/* 45 ( 69) */ HID_KEY_0,
|
||||
/* 46 ( 70) */ HID_KEY_9,
|
||||
/* 47 ( 71) */ 0x00,
|
||||
/* 48 ( 72) */ HID_KEY_F21,
|
||||
/* 49 ( 73) */ HID_KEY_PERIOD,
|
||||
/* 4A ( 74) */ HID_KEY_SLASH,
|
||||
/* 4B ( 75) */ HID_KEY_L,
|
||||
/* 4C ( 76) */ HID_KEY_SEMICOLON,
|
||||
/* 4D ( 77) */ HID_KEY_P,
|
||||
/* 4E ( 78) */ HID_KEY_MINUS,
|
||||
/* 4F ( 79) */ 0x00,
|
||||
/* 50 ( 80) */ HID_KEY_F22,
|
||||
/* 51 ( 81) */ 0x00,
|
||||
/* 52 ( 82) */ HID_KEY_APOSTROPHE,
|
||||
/* 53 ( 83) */ 0x00,
|
||||
/* 54 ( 84) */ HID_KEY_BRACKET_LEFT,
|
||||
/* 55 ( 85) */ HID_KEY_EQUAL,
|
||||
/* 56 ( 86) */ 0x00,
|
||||
/* 57 ( 87) */ HID_KEY_F23,
|
||||
/* 58 ( 88) */ HID_KEY_CAPS_LOCK,
|
||||
/* 59 ( 89) */ HID_KEY_SHIFT_RIGHT,
|
||||
/* 5A ( 90) */ HID_KEY_ENTER, // RETURN ??
|
||||
/* 5B ( 91) */ HID_KEY_BRACKET_RIGHT,
|
||||
/* 5C ( 92) */ 0x00,
|
||||
/* 5D ( 93) */ HID_KEY_EUROPE_1,
|
||||
/* 5E ( 94) */ 0x00,
|
||||
/* 5F ( 95) */ HID_KEY_F24,
|
||||
/* 60 ( 96) */ 0x00,
|
||||
/* 61 ( 97) */ HID_KEY_EUROPE_2,
|
||||
/* 62 ( 98) */ 0x00,
|
||||
/* 63 ( 99) */ 0x00,
|
||||
/* 64 (100) */ 0x00,
|
||||
/* 65 (101) */ 0x00,
|
||||
/* 66 (102) */ HID_KEY_BACKSPACE,
|
||||
/* 67 (103) */ 0x00,
|
||||
/* 68 (104) */ 0x00,
|
||||
/* 69 (105) */ HID_KEY_KEYPAD_1,
|
||||
/* 6A (106) */ 0x00,
|
||||
/* 6B (107) */ HID_KEY_KEYPAD_4,
|
||||
/* 6C (108) */ HID_KEY_KEYPAD_7,
|
||||
/* 6D (109) */ 0x00,
|
||||
/* 6E (110) */ 0x00,
|
||||
/* 6F (111) */ 0x00,
|
||||
/* 70 (112) */ HID_KEY_KEYPAD_0,
|
||||
/* 71 (113) */ HID_KEY_KEYPAD_DECIMAL,
|
||||
/* 72 (114) */ HID_KEY_KEYPAD_2,
|
||||
/* 73 (115) */ HID_KEY_KEYPAD_5,
|
||||
/* 74 (116) */ HID_KEY_KEYPAD_6,
|
||||
/* 75 (117) */ HID_KEY_KEYPAD_8,
|
||||
/* 76 (118) */ HID_KEY_ESCAPE,
|
||||
/* 77 (119) */ HID_KEY_NUM_LOCK,
|
||||
/* 78 (120) */ HID_KEY_F11,
|
||||
/* 79 (121) */ HID_KEY_KEYPAD_ADD,
|
||||
/* 7A (122) */ HID_KEY_KEYPAD_3,
|
||||
/* 7B (123) */ HID_KEY_KEYPAD_SUBTRACT,
|
||||
/* 7C (124) */ HID_KEY_KEYPAD_MULTIPLY,
|
||||
/* 7D (125) */ HID_KEY_KEYPAD_9,
|
||||
/* 7E (126) */ HID_KEY_SCROLL_LOCK,
|
||||
/* 7F (127) */ 0x00,
|
||||
/* 80 (128) */ 0x00,
|
||||
/* 81 (129) */ 0x00,
|
||||
/* 82 (130) */ 0x00,
|
||||
/* 83 (131) */ HID_KEY_F7
|
||||
};
|
||||
|
||||
Ps2Kbd_Mrmltr::Ps2Kbd_Mrmltr(PIO pio, uint base_gpio, std::function<void(hid_keyboard_report_t *curr, hid_keyboard_report_t *prev)> keyHandler) :
|
||||
_pio(pio),
|
||||
_base_gpio(base_gpio),
|
||||
_double(false),
|
||||
_overflow(false),
|
||||
_keyHandler(keyHandler)
|
||||
{
|
||||
clearHidKeys();
|
||||
clearActions();
|
||||
}
|
||||
|
||||
void Ps2Kbd_Mrmltr::clearHidKeys() {
|
||||
_report.modifier = 0;
|
||||
for (int i = 0; i < HID_KEYBOARD_REPORT_MAX_KEYS; ++i) _report.keycode[i] = HID_KEY_NONE;
|
||||
}
|
||||
|
||||
inline static uint8_t hidKeyToMod(uint8_t hidKeyCode) {
|
||||
uint8_t m = 0;
|
||||
switch(hidKeyCode) {
|
||||
case HID_KEY_CONTROL_LEFT: m = KEYBOARD_MODIFIER_LEFTCTRL; break;
|
||||
case HID_KEY_SHIFT_LEFT: m = KEYBOARD_MODIFIER_LEFTSHIFT; break;
|
||||
case HID_KEY_ALT_LEFT: m = KEYBOARD_MODIFIER_LEFTALT; break;
|
||||
case HID_KEY_GUI_LEFT: m = KEYBOARD_MODIFIER_LEFTGUI; break;
|
||||
case HID_KEY_CONTROL_RIGHT: m = KEYBOARD_MODIFIER_RIGHTCTRL; break;
|
||||
case HID_KEY_SHIFT_RIGHT: m = KEYBOARD_MODIFIER_RIGHTSHIFT; break;
|
||||
case HID_KEY_ALT_RIGHT: m = KEYBOARD_MODIFIER_RIGHTALT; break;
|
||||
case HID_KEY_GUI_RIGHT: m = KEYBOARD_MODIFIER_RIGHTGUI; break;
|
||||
default: break;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
void Ps2Kbd_Mrmltr::handleHidKeyPress(uint8_t hidKeyCode) {
|
||||
hid_keyboard_report_t prev = _report;
|
||||
|
||||
// Check the key is not alreay pressed
|
||||
for (int i = 0; i < HID_KEYBOARD_REPORT_MAX_KEYS; ++i) {
|
||||
if (_report.keycode[i] == hidKeyCode) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_report.modifier |= hidKeyToMod(hidKeyCode);
|
||||
|
||||
for (int i = 0; i < HID_KEYBOARD_REPORT_MAX_KEYS; ++i) {
|
||||
if (_report.keycode[i] == HID_KEY_NONE) {
|
||||
_report.keycode[i] = hidKeyCode;
|
||||
_keyHandler(&_report, &prev);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Overflow
|
||||
DBG_PRINTF("PS/2 keyboard HID overflow\n");
|
||||
}
|
||||
|
||||
void Ps2Kbd_Mrmltr::handleHidKeyRelease(uint8_t hidKeyCode) {
|
||||
hid_keyboard_report_t prev = _report;
|
||||
|
||||
_report.modifier &= ~hidKeyToMod(hidKeyCode);
|
||||
|
||||
for (int i = 0; i < HID_KEYBOARD_REPORT_MAX_KEYS; ++i) {
|
||||
if (_report.keycode[i] == hidKeyCode) {
|
||||
_report.keycode[i] = HID_KEY_NONE;
|
||||
_keyHandler(&_report, &prev);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t Ps2Kbd_Mrmltr::hidCodePage0(uint8_t ps2code) {
|
||||
return ps2code < sizeof(ps2kbd_page_0) ? ps2kbd_page_0[ps2code] : HID_KEY_NONE;
|
||||
}
|
||||
|
||||
// PS/2 set 2 after 0xe0 to HID key conversion
|
||||
uint8_t Ps2Kbd_Mrmltr::hidCodePage1(uint8_t ps2code) {
|
||||
switch(ps2code) {
|
||||
// TODO these belong to a different HID usage page
|
||||
// case 0x37: return HID_KEY_POWER;
|
||||
// case 0x3f: return HID_KEY_SLEEP;
|
||||
// case 0x5e: return HID_KEY_WAKE;
|
||||
case 0x11: return HID_KEY_ALT_RIGHT;
|
||||
case 0x1f: return HID_KEY_GUI_LEFT;
|
||||
case 0x14: return HID_KEY_CONTROL_RIGHT;
|
||||
case 0x27: return HID_KEY_GUI_RIGHT;
|
||||
case 0x4a: return HID_KEY_KEYPAD_DIVIDE;
|
||||
case 0x5a: return HID_KEY_KEYPAD_ENTER;
|
||||
case 0x69: return HID_KEY_END;
|
||||
case 0x6b: return HID_KEY_ARROW_LEFT;
|
||||
case 0x6c: return HID_KEY_HOME;
|
||||
case 0x7c: return HID_KEY_PRINT_SCREEN;
|
||||
case 0x70: return HID_KEY_INSERT;
|
||||
case 0x71: return HID_KEY_DELETE;
|
||||
case 0x72: return HID_KEY_ARROW_DOWN;
|
||||
case 0x74: return HID_KEY_ARROW_RIGHT;
|
||||
case 0x75: return HID_KEY_ARROW_UP;
|
||||
case 0x7a: return HID_KEY_PAGE_DOWN;
|
||||
case 0x7d: return HID_KEY_PAGE_UP;
|
||||
|
||||
default:
|
||||
return HID_KEY_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
void Ps2Kbd_Mrmltr::handleActions() {
|
||||
#ifdef DEBUG_PS2
|
||||
for (uint i = 0; i <= _action; ++i) {
|
||||
DBG_PRINTF("PS/2 key %s page %2.2X (%3.3d) code %2.2X (%3.3d)\n",
|
||||
_actions[i].release ? "release" : "press",
|
||||
_actions[i].page,
|
||||
_actions[i].page,
|
||||
_actions[i].code,
|
||||
_actions[i].code);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t hidCode;
|
||||
bool release;
|
||||
if (_action == 0) {
|
||||
switch (_actions[0].page) {
|
||||
case 1: {
|
||||
hidCode = hidCodePage1(_actions[0].code);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
hidCode = hidCodePage0(_actions[0].code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
release = _actions[0].release;
|
||||
}
|
||||
else {
|
||||
// TODO get the HID code for extended PS/2 codes
|
||||
hidCode = HID_KEY_NONE;
|
||||
release = false;
|
||||
}
|
||||
|
||||
if (hidCode != HID_KEY_NONE) {
|
||||
|
||||
DBG_PRINTF("HID key %s code %2.2X (%3.3d)\n",
|
||||
release ? "release" : "press",
|
||||
hidCode,
|
||||
hidCode);
|
||||
|
||||
if (release) {
|
||||
handleHidKeyRelease(hidCode);
|
||||
}
|
||||
else {
|
||||
handleHidKeyPress(hidCode);
|
||||
}
|
||||
}
|
||||
|
||||
DBG_PRINTF("PS/2 HID m=%2X ", _report.modifier);
|
||||
#ifdef DEBUG_PS2
|
||||
for (int i = 0; i < HID_KEYBOARD_REPORT_MAX_KEYS; ++i) printf("%2X ", _report.keycode[i]);
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void Ps2Kbd_Mrmltr::tick() {
|
||||
if (pio_sm_is_rx_fifo_full(_pio, _sm)) {
|
||||
DBG_PRINTF("PS/2 keyboard PIO overflow\n");
|
||||
_overflow = true;
|
||||
while (!pio_sm_is_rx_fifo_empty(_pio, _sm)) {
|
||||
// pull a scan code from the PIO SM fifo
|
||||
uint32_t rc = _pio->rxf[_sm];
|
||||
printf("PS/2 drain rc %4.4lX (%ld)\n", rc, rc);
|
||||
}
|
||||
clearHidKeys();
|
||||
clearActions();
|
||||
}
|
||||
|
||||
while (!pio_sm_is_rx_fifo_empty(_pio, _sm)) {
|
||||
// pull a scan code from the PIO SM fifo
|
||||
uint32_t rc = _pio->rxf[_sm];
|
||||
DBG_PRINTF("PS/2 rc %4.4lX (%ld)\n", rc, rc);
|
||||
|
||||
uint32_t code = (rc << 2) >> 24;
|
||||
DBG_PRINTF("PS/2 keycode %2.2lX (%ld)\n", code, code);
|
||||
|
||||
// TODO Handle PS/2 overflow/error messages
|
||||
switch (code) {
|
||||
case 0xaa: {
|
||||
DBG_PRINTF("PS/2 keyboard Self test passed\n");
|
||||
break;
|
||||
}
|
||||
case 0xe1: {
|
||||
_double = true;
|
||||
break;
|
||||
}
|
||||
case 0xe0: {
|
||||
_actions[_action].page = 1;
|
||||
break;
|
||||
}
|
||||
case 0xf0: {
|
||||
_actions[_action].release = true;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
_actions[_action].code = code;
|
||||
if (_double) {
|
||||
_action = 1;
|
||||
_double = false;
|
||||
}
|
||||
else {
|
||||
handleActions();
|
||||
clearActions();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Error checking and reporting
|
||||
void Ps2Kbd_Mrmltr::init_gpio() {
|
||||
// init KBD pins to input
|
||||
gpio_init(_base_gpio); // Data
|
||||
gpio_init(_base_gpio + 1); // Clock
|
||||
// with pull up
|
||||
gpio_pull_up(_base_gpio);
|
||||
gpio_pull_up(_base_gpio + 1);
|
||||
// get a state machine
|
||||
_sm = pio_claim_unused_sm(_pio, true);
|
||||
// reserve program space in SM memory
|
||||
uint offset = pio_add_program(_pio, &ps2kbd_program);
|
||||
// Set pin directions base
|
||||
pio_sm_set_consecutive_pindirs(_pio, _sm, _base_gpio, 2, false);
|
||||
// program the start and wrap SM registers
|
||||
pio_sm_config c = ps2kbd_program_get_default_config(offset);
|
||||
// Set the base input pin. pin index 0 is DAT, index 1 is CLK // Murmulator: 0->CLK 1->DAT ( _base_gpio + 1)
|
||||
// sm_config_set_in_pins(&c, _base_gpio);
|
||||
sm_config_set_in_pins(&c, _base_gpio + 1);
|
||||
// Shift 8 bits to the right, autopush enabled
|
||||
sm_config_set_in_shift(&c, true, true, 10);
|
||||
// Deeper FIFO as we're not doing any TX
|
||||
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX);
|
||||
// We don't expect clock faster than 16.7KHz and want no less
|
||||
// than 8 SM cycles per keyboard clock.
|
||||
float div = (float)clock_get_hz(clk_sys) / (8 * 16700);
|
||||
sm_config_set_clkdiv(&c, div);
|
||||
// Ready to go
|
||||
pio_sm_init(_pio, _sm, offset, &c);
|
||||
pio_sm_set_enabled(_pio, _sm, true);
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
// You may use, distribute and modify this code under the
|
||||
// terms of the GPLv2 license, which unfortunately won't be
|
||||
// written for another century.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "tusb.h"
|
||||
#include "hardware/pio.h"
|
||||
#include "hardware/gpio.h"
|
||||
#include <functional>
|
||||
|
||||
typedef struct {
|
||||
uint8_t code;
|
||||
bool release;
|
||||
uint8_t page;
|
||||
} Ps2KbdAction_;
|
||||
|
||||
class Ps2Kbd_Mrmltr {
|
||||
private:
|
||||
PIO _pio; // pio0 or pio1
|
||||
uint _sm; // pio state machine index
|
||||
uint _base_gpio; // data signal gpio
|
||||
hid_keyboard_report_t _report; // HID report structure
|
||||
Ps2KbdAction_ _actions[2];
|
||||
uint _action;
|
||||
bool _double;
|
||||
bool _overflow;
|
||||
|
||||
std::function<void(hid_keyboard_report_t *curr, hid_keyboard_report_t *prev)> _keyHandler;
|
||||
|
||||
inline void clearActions() {
|
||||
_actions[0].page = 0;
|
||||
_actions[0].release = false;
|
||||
_actions[0].code = 0;
|
||||
_actions[1].page = 0;
|
||||
_actions[1].release = false;
|
||||
_actions[1].code = 0;
|
||||
_action = 0;
|
||||
}
|
||||
|
||||
void __not_in_flash_func(handleHidKeyPress)(uint8_t hidKeyCode);
|
||||
void __not_in_flash_func(handleHidKeyRelease)(uint8_t hidKeyCode);
|
||||
|
||||
void __not_in_flash_func(handleActions)();
|
||||
uint8_t __not_in_flash_func(hidCodePage0)(uint8_t ps2code);
|
||||
uint8_t __not_in_flash_func(hidCodePage1)(uint8_t ps2code);
|
||||
void clearHidKeys();
|
||||
|
||||
public:
|
||||
|
||||
Ps2Kbd_Mrmltr(
|
||||
PIO pio,
|
||||
uint base_gpio,
|
||||
std::function<void(hid_keyboard_report_t *curr, hid_keyboard_report_t *prev)> keyHandler);
|
||||
|
||||
void init_gpio();
|
||||
|
||||
void __not_in_flash_func(tick)();
|
||||
};
|
@ -1,23 +0,0 @@
|
||||
; Copyright (C) 1883 Thomas Edison - All Rights Reserved
|
||||
; You may use, distribute and modify this code under the
|
||||
; terms of the GPLv2 license, which unfortunately won't be
|
||||
; written for another century.
|
||||
;
|
||||
; SPDX-License-Identifier: GPL-2.0-or-later
|
||||
;
|
||||
.program ps2kbd
|
||||
|
||||
; Ps2 for MURMULATOR 0->CLK 1->DAT
|
||||
;================================================
|
||||
wait 0 gpio 0 ; skip start bit
|
||||
wait 1 gpio 0
|
||||
;----------------------
|
||||
set x, 9 ; 8 bit counter
|
||||
bitloop:
|
||||
wait 0 gpio 0 [1] ; wait negative clock edge
|
||||
;----------------------
|
||||
in pins, 1 ; sample data
|
||||
wait 1 gpio 0 ; wait for positive edge
|
||||
;----------------------
|
||||
jmp x-- bitloop
|
||||
|
32
src/pwm.pio
Normal file
32
src/pwm.pio
Normal file
@ -0,0 +1,32 @@
|
||||
;
|
||||
; Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
;
|
||||
; SPDX-License-Identifier: BSD-3-Clause
|
||||
;
|
||||
|
||||
; Side-set pin 0 is used for PWM output
|
||||
.pio_version 0 // only requires PIO version 0
|
||||
|
||||
.program pwm
|
||||
.side_set 1 opt
|
||||
|
||||
pull noblock side 0 ; Pull from FIFO to OSR if available, else copy X to OSR.
|
||||
mov x, osr ; Copy most-recently-pulled value back to scratch X
|
||||
mov y, isr ; ISR contains PWM period. Y used as counter.
|
||||
countloop:
|
||||
jmp x!=y noset ; Set pin high if X == Y, keep the two paths length matched
|
||||
jmp skip side 1
|
||||
noset:
|
||||
nop ; Single dummy cycle to keep the two paths the same length
|
||||
skip:
|
||||
jmp y-- countloop ; Loop until Y hits 0, then pull a fresh PWM value from FIFO
|
||||
|
||||
% c-sdk {
|
||||
static inline void pwm_program_init(PIO pio, uint sm, uint offset, uint pin) {
|
||||
pio_gpio_init(pio, pin);
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
|
||||
pio_sm_config c = pwm_program_get_default_config(offset);
|
||||
sm_config_set_sideset_pins(&c, pin);
|
||||
pio_sm_init(pio, sm, offset, &c);
|
||||
}
|
||||
%}
|
@ -180,7 +180,7 @@ set(ZxSpectrumPicoMiteVGA_defines
|
||||
SPK_PIN=7
|
||||
# Enable the PS/2 keyboard
|
||||
USE_PS2_KBD
|
||||
USE_MRMLTR_PS2_KBD
|
||||
PS2KBD_CLK0_DAT
|
||||
# Use stdio
|
||||
USE_STDIO
|
||||
)
|
||||
@ -192,12 +192,15 @@ foreach(target
|
||||
ZX-MURMULATOR_VGA_PWM_AUDIO_720x576x50Hz
|
||||
ZX-MURMULATOR_VGA_I2S_AUDIO_640x480x60Hz
|
||||
ZX-MURMULATOR_VGA_I2S_AUDIO_720x576x50Hz
|
||||
ZX-MURMULATOR2_VGA_PWM_AUDIO_640x480x60Hz
|
||||
ZX-MURMULATOR2_VGA_PWM_AUDIO_720x576x50Hz
|
||||
ZX-MURMULATOR2_VGA_I2S_AUDIO_640x480x60Hz
|
||||
ZX-MURMULATOR2_VGA_I2S_AUDIO_720x576x50Hz
|
||||
)
|
||||
|
||||
add_executable(${target}
|
||||
${zxspectrum_common_src}
|
||||
${zxspectrum_rgb_src}
|
||||
${murmulator_common_src}
|
||||
${zxspectrum_scanvideo_src}
|
||||
main.cpp
|
||||
)
|
||||
@ -218,8 +221,12 @@ foreach(target
|
||||
${zxspectrum_ear_in_pio}
|
||||
)
|
||||
|
||||
pico_generate_pio_header(${target}
|
||||
${murmulator_ps2kbd_pio}
|
||||
pico_generate_pio_header(${target}
|
||||
${zxspectrum_audio_i2s_pio}
|
||||
)
|
||||
|
||||
pico_generate_pio_header(${target}
|
||||
${zxspectrum_pwm_pio}
|
||||
)
|
||||
|
||||
pico_enable_stdio_usb(${target} 0)
|
||||
@ -252,7 +259,7 @@ target_compile_definitions(ZxSpectrumPicoMiteVGA_640x480x60Hz PRIVATE
|
||||
# ZX MURMULATOR
|
||||
#========================================================
|
||||
set(ZX-MURMULATOR_VGA_defines
|
||||
MURMULATOR
|
||||
ZX_PLATFORM="MURMULATOR"
|
||||
# Configure the SPI sd card to use SPI0
|
||||
SDCARD_PIN_SPI0_CS=5
|
||||
SDCARD_PIN_SPI0_SCK=2
|
||||
@ -275,7 +282,7 @@ set(ZX-MURMULATOR_VGA_defines
|
||||
EAR_PIN=22
|
||||
# Enable the PS/2 keyboard
|
||||
USE_PS2_KBD
|
||||
USE_MRMLTR_PS2_KBD
|
||||
PS2KBD_CLK0_DAT
|
||||
# Pins for dual NES joypads, pio1 SM ?
|
||||
NESPAD_DATA_PIN_BASE=16
|
||||
NESPAD_CLK_PIN_BASE=14
|
||||
@ -317,19 +324,6 @@ foreach(target
|
||||
|
||||
endforeach()
|
||||
|
||||
foreach(target
|
||||
ZX-MURMULATOR_VGA_I2S_AUDIO_640x480x60Hz
|
||||
ZX-MURMULATOR_VGA_I2S_AUDIO_720x576x50Hz
|
||||
)
|
||||
|
||||
pico_generate_pio_header(${target}
|
||||
${zxspectrum_audio_i2s_pio}
|
||||
)
|
||||
|
||||
endforeach()
|
||||
|
||||
|
||||
|
||||
target_compile_definitions(ZX-MURMULATOR_VGA_PWM_AUDIO_640x480x60Hz PRIVATE
|
||||
${ZX-MURMULATOR_VGA_defines}
|
||||
${ZX-MURMULATOR_VGA_PWM_Audio_defines}
|
||||
@ -352,4 +346,98 @@ target_compile_definitions(ZX-MURMULATOR_VGA_I2S_AUDIO_720x576x50Hz PRIVATE
|
||||
${ZX-MURMULATOR_VGA_defines}
|
||||
${ZX-MURMULATOR_VGA_I2S_Audio_defines}
|
||||
${zxspectrum_vga_720x576x50Hz_defines}
|
||||
)
|
||||
)
|
||||
|
||||
#========================================================
|
||||
# ZX MURMULATOR2
|
||||
#========================================================
|
||||
set(ZX-MURMULATOR2_VGA_defines
|
||||
ZX_PLATFORM="MURMULATOR2"
|
||||
# Configure the SPI sd card to use SPI0
|
||||
SDCARD_PIN_SPI0_CS=5
|
||||
SDCARD_PIN_SPI0_SCK=6
|
||||
SDCARD_PIN_SPI0_MOSI=7
|
||||
SDCARD_PIN_SPI0_MISO=4
|
||||
#VGA 222 vith VSYNC
|
||||
VGA_ENC_RGB_222
|
||||
VGA_VSYNC
|
||||
PICO_SCANVIDEO_COLOR_PIN_COUNT=6u
|
||||
PICO_SCANVIDEO_DPI_PIXEL_RCOUNT=2u
|
||||
PICO_SCANVIDEO_DPI_PIXEL_GCOUNT=2u
|
||||
PICO_SCANVIDEO_DPI_PIXEL_BCOUNT=3u
|
||||
PICO_SCANVIDEO_DPI_PIXEL_RSHIFT=4u
|
||||
PICO_SCANVIDEO_DPI_PIXEL_GSHIFT=2u
|
||||
PICO_SCANVIDEO_DPI_PIXEL_BSHIFT=0u
|
||||
PICO_SCANVIDEO_COLOR_PIN_BASE=12u
|
||||
# Use the alternate volume map
|
||||
AY8912_ALT_VOL_MAP
|
||||
# Tape audio in
|
||||
EAR_PIN=22
|
||||
# Enable the PS/2 keyboard
|
||||
USE_PS2_KBD
|
||||
PS2KBD_CLK2_DAT
|
||||
# Pins for dual NES joypads, pio1 SM ?
|
||||
NESPAD_DATA_PIN_BASE=26
|
||||
NESPAD_CLK_PIN_BASE=20
|
||||
NESPAD_PIO=pio1
|
||||
NESPAD_IRQ=PIO1_IRQ_0
|
||||
NESPAD_ENABLE
|
||||
)
|
||||
|
||||
set(ZX-MURMULATOR2_VGA_PWM_Audio_defines
|
||||
#
|
||||
# This could be ABC output on GPIO 10, 9, 11 but the sofware FIFO is not working on the RP2350
|
||||
# For now I will output mono PWM using a PIO block on GPIO 10
|
||||
#
|
||||
PICO_AUDIO_PWM_PIO=pio1
|
||||
PICO_PIO_PWM_AUDIO
|
||||
SPK_PIN=9
|
||||
)
|
||||
|
||||
set (ZX-MURMULATOR2_VGA_I2S_Audio_defines
|
||||
# Configure the I2S audio, pio1 SM ?
|
||||
PICO_AUDIO_I2S=1
|
||||
PICO_AUDIO_I2S_PIO=pio1
|
||||
PICO_AUDIO_I2S_PIO_FUNC=GPIO_FUNC_PIO1
|
||||
PICO_AUDIO_I2S_DATA=9
|
||||
PICO_AUDIO_I2S_BCLK=10
|
||||
)
|
||||
|
||||
foreach(target
|
||||
ZX-MURMULATOR2_VGA_PWM_AUDIO_640x480x60Hz
|
||||
ZX-MURMULATOR2_VGA_PWM_AUDIO_720x576x50Hz
|
||||
ZX-MURMULATOR2_VGA_I2S_AUDIO_640x480x60Hz
|
||||
ZX-MURMULATOR2_VGA_I2S_AUDIO_720x576x50Hz
|
||||
)
|
||||
pico_enable_stdio_uart(${target} 1)
|
||||
|
||||
endforeach()
|
||||
|
||||
target_compile_definitions(ZX-MURMULATOR2_VGA_PWM_AUDIO_640x480x60Hz PRIVATE
|
||||
${ZX-MURMULATOR2_VGA_defines}
|
||||
${ZX-MURMULATOR2_VGA_PWM_Audio_defines}
|
||||
${zxspectrum_vga_640x480x60Hz_defines}
|
||||
# Speaker pin audio (@250MHz 250000000 / (1000 * 3 * 2))
|
||||
PICO_PWM_AUDIO_FREQ=41666
|
||||
)
|
||||
|
||||
target_compile_definitions(ZX-MURMULATOR2_VGA_PWM_AUDIO_720x576x50Hz PRIVATE
|
||||
${ZX-MURMULATOR2_VGA_defines}
|
||||
${ZX-MURMULATOR2_VGA_PWM_Audio_defines}
|
||||
${zxspectrum_vga_720x576x50Hz_defines}
|
||||
# Speaker pin audio (@270MHz 270000000 / (1000 * 3 * 2))
|
||||
PICO_PWM_AUDIO_FREQ=45000
|
||||
)
|
||||
|
||||
target_compile_definitions(ZX-MURMULATOR2_VGA_I2S_AUDIO_640x480x60Hz PRIVATE
|
||||
${ZX-MURMULATOR2_VGA_defines}
|
||||
${ZX-MURMULATOR2_VGA_I2S_Audio_defines}
|
||||
${zxspectrum_vga_640x480x60Hz_defines}
|
||||
)
|
||||
|
||||
target_compile_definitions(ZX-MURMULATOR2_VGA_I2S_AUDIO_720x576x50Hz PRIVATE
|
||||
${ZX-MURMULATOR2_VGA_defines}
|
||||
${ZX-MURMULATOR2_VGA_I2S_Audio_defines}
|
||||
${zxspectrum_vga_720x576x50Hz_defines}
|
||||
)
|
||||
|
||||
|
@ -1,14 +1,10 @@
|
||||
#include <stdio.h>
|
||||
#include "pico/stdlib.h"
|
||||
#include "pico/multicore.h"
|
||||
#include "hardware/vreg.h"
|
||||
#include "PicoCoreVoltage.h"
|
||||
#include "hardware/pwm.h"
|
||||
|
||||
#ifdef USE_MRMLTR_PS2_KBD
|
||||
#include "ps2kbd_mrmltr.h"
|
||||
#else
|
||||
#include "ps2kbd.h"
|
||||
#endif
|
||||
|
||||
// #include "pzx_keyscan.h"
|
||||
|
||||
@ -183,16 +179,10 @@ void __not_in_flash_func(process_joystick)() {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_MRMLTR_PS2_KBD
|
||||
static Ps2Kbd_Mrmltr ps2kbd(
|
||||
pio1,
|
||||
0,
|
||||
process_kbd_report
|
||||
);
|
||||
#elif defined(USE_PS2_KBD)
|
||||
#if defined(USE_PS2_KBD)
|
||||
static Ps2Kbd ps2kbd(
|
||||
pio1,
|
||||
6,
|
||||
PS2KBD_GPIO,
|
||||
process_kbd_report
|
||||
);
|
||||
#endif
|
||||
@ -265,8 +255,7 @@ int main(){
|
||||
gpio_init(LED_PIN);
|
||||
gpio_set_dir(LED_PIN, GPIO_OUT);
|
||||
|
||||
vreg_set_voltage(VREG_VSEL);
|
||||
sleep_ms(10);
|
||||
pico_set_core_voltage();
|
||||
|
||||
ZxScanlineVgaRenderLoopInit();
|
||||
|
||||
@ -359,3 +348,4 @@ int main(){
|
||||
|
||||
main_loop();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user