mirror of
https://github.com/polpo/picogus.git
synced 2026-10-25 21:40:16 +00:00
Big overhaul of pgusinit; break out common stuff
This commit is contained in:
1 parent
be1ff1b273
commit
e216fdc0ad
17 files changed
+811
-693
No files matched your search
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
// names, mode numbers, port numbers, etc., that are common between the PicoGUS firmware and pgusinit.exe
|
||||
|
||||
// 1D0 chosen as the base port as nothing is listed in Ralf Brown's Port List (http://www.cs.cmu.edu/~ralf/files.html)
|
||||
#define CONTROL_PORT 0x1D0
|
||||
#define DATA_PORT_LOW 0x1D1
|
||||
#define DATA_PORT_HIGH 0x1D2
|
||||
#define PICOGUS_PROTOCOL_VER 3
|
||||
|
||||
typedef enum {
|
||||
PICO_FIRMWARE_IDLE = 0,
|
||||
PICO_FIRMWARE_WRITING = 1,
|
||||
PICO_FIRMWARE_BUSY = 2,
|
||||
PICO_FIRMWARE_DONE = 0xFE,
|
||||
PICO_FIRMWARE_ERROR = 0xFF
|
||||
} pico_firmware_status_t;
|
||||
|
||||
typedef enum { PICO_BASED = 0, PICOGUS_2 = 1 } board_type_t;
|
||||
|
||||
typedef enum {
|
||||
INVALID_MODE = 0,
|
||||
GUS_MODE = 1,
|
||||
ADLIB_MODE = 2,
|
||||
MPU_MODE = 3,
|
||||
TANDY_MODE = 4,
|
||||
CMS_MODE = 5,
|
||||
SB_MODE = 6,
|
||||
USB_MODE = 7
|
||||
} card_mode_t;
|
||||
|
||||
static const char *modenames[8] = {
|
||||
"INVALID",
|
||||
"GUS",
|
||||
"ADLIB",
|
||||
"MPU",
|
||||
"TANDY",
|
||||
"CMS",
|
||||
"SB",
|
||||
"USB"
|
||||
};
|
||||
|
||||
#define MODE_MAGIC 0x00 // Magic string
|
||||
#define MODE_PROTOCOL 0x01 // Protocol version
|
||||
#define MODE_FWSTRING 0x02 // Firmware string
|
||||
#define MODE_MODE 0x03 // Mode (GUS, OPL, MPU, etc...)
|
||||
#define MODE_GUSPORT 0x04 // GUS Base port
|
||||
#define MODE_OPLPORT 0x05 // Adlib Base port
|
||||
#define MODE_SBPORT 0x06 // SB Base port
|
||||
#define MODE_MPUPORT 0x07 // MPU Base port
|
||||
#define MODE_TANDYPORT 0x08 // Tandy Base port
|
||||
#define MODE_CMSPORT 0x09 // CMS Base port
|
||||
#define MODE_JOYEN 0x0f // enable joystick
|
||||
#define MODE_GUSBUF 0x10 // Audio buffer size
|
||||
#define MODE_GUSDMA 0x11 // DMA interval
|
||||
#define MODE_GUS44K 0x12 // Force 44k
|
||||
#define MODE_WTVOL 0x20 // Wavetable mixer volume
|
||||
#define MODE_MPUDELAY 0x21 // MPU sysex delay
|
||||
#define MODE_MPUFAKE 0x22 // MPU fake all notes off
|
||||
#define MODE_OPLWAIT 0x30 // Adlib speed sensitive fix
|
||||
#define MODE_MOUSEPORT 0x40 // Mouse Base port
|
||||
#define MODE_MOUSEPROTO 0x41 // Mouse protocol
|
||||
#define MODE_MOUSERATE 0x42 // Mouse report rate
|
||||
#define MODE_MOUSESEN 0x43 // Mouse sensitivity
|
||||
#define MODE_BOOTMODE 0xE0 // Select firmware boot mode register
|
||||
#define MODE_SAVE 0xE1 // Select save settings register
|
||||
#define MODE_REBOOT 0xE2 // Select reboot register
|
||||
#define MODE_DEFAULTS 0xE3 // Select reset to defaults register
|
||||
#define MODE_HWTYPE 0xF0 // Hardware type
|
||||
#define MODE_FLASH 0xFF // Firmware write mode
|
||||
@@ -1,5 +1,5 @@
|
||||
CC = wcl
|
||||
CFLAGS = -bcl=dos -za99
|
||||
CFLAGS = -bcl=dos -za99 -os
|
||||
|
||||
pgusinit.exe: pgusinit.c
|
||||
$(CC) $(CFLAGS) $<
|
||||
|
||||
+339
-319
@@ -7,40 +7,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <i86.h>
|
||||
|
||||
#define CONTROL_PORT 0x1D0
|
||||
#define DATA_PORT_LOW 0x1D1
|
||||
#define DATA_PORT_HIGH 0x1D2
|
||||
#define PICOGUS_PROTOCOL_VER 2
|
||||
|
||||
typedef enum {
|
||||
PICO_FIRMWARE_IDLE = 0,
|
||||
PICO_FIRMWARE_WRITING = 1,
|
||||
PICO_FIRMWARE_DONE = 0xFE,
|
||||
PICO_FIRMWARE_ERROR = 0xFF
|
||||
} pico_firmware_status_t;
|
||||
|
||||
typedef enum { PICO_BASED = 0, PICOGUS_2 = 1 } board_type_t;
|
||||
|
||||
typedef enum {
|
||||
GUS_MODE = 0,
|
||||
ADLIB_MODE = 1,
|
||||
MPU_MODE = 2,
|
||||
TANDY_MODE = 3,
|
||||
CMS_MODE = 4,
|
||||
SB_MODE = 5,
|
||||
MOUSE_ONLY_MODE = 0x0e,
|
||||
JOYSTICK_ONLY_MODE = 0x0f
|
||||
} card_mode_t;
|
||||
|
||||
static const char *fwnames[8] = {
|
||||
"INVALID",
|
||||
"GUS",
|
||||
"SB",
|
||||
"MPU",
|
||||
"TANDY",
|
||||
"CMS",
|
||||
"JOY"
|
||||
};
|
||||
#include "../common/picogus.h"
|
||||
|
||||
void banner(void) {
|
||||
printf("PicoGUSinit v3.0.0 (c) 2024 Ian Scott - licensed under the GNU GPL v2\n\n");
|
||||
@@ -58,62 +25,78 @@ const char* usage_by_card[] = {
|
||||
"", // JOYSTICK_ONLY_MODE
|
||||
};
|
||||
|
||||
void usage(char *argv0, card_mode_t mode) {
|
||||
void usage(char *argv0, card_mode_t mode, bool print_all) {
|
||||
// Max line length @ 80 chars:
|
||||
// "................................................................................\n"
|
||||
fprintf(stderr, "Usage:\n");
|
||||
fprintf(stderr, " %s [/?] | [/f fw.uf2] | [/m x [d]]", argv0);
|
||||
if (mode <= CMS_MODE) {
|
||||
fprintf(stderr, " | [/j] %s", usage_by_card[mode]);
|
||||
// "................................................................................\n"
|
||||
printf("Usage:\n");
|
||||
printf(" /? - show this message (/?? to show options for all modes)\n");
|
||||
printf(" /flash fw.uf2 - program the PicoGUS with the firmware file fw.uf2\n");
|
||||
printf(" /wtvol x - set volume of wavetable header. Scale 0-100, Default: 100\n");
|
||||
printf(" (for PicoGUS v2.0 boards only)\n");
|
||||
printf(" /mode x - change card mode to x (gus, sb, mpu, tandy, cms, usb)\n");
|
||||
printf(" /defaults - set all settings for all modes to defaults\n");
|
||||
printf(" /save - save settings to the card to persist on system boot\n");
|
||||
printf(" /joy 1|0 - enable/disable USB joystick support\n");
|
||||
printf("\n");
|
||||
if (mode == GUS_MODE || print_all) {
|
||||
// "................................................................................\n"
|
||||
printf("GUS mode settings:\n");
|
||||
printf(" /gusport x - set the base port of the GUS. Default: 240\n");
|
||||
printf(" /gusbuf n - set audio buffer to n samples. Default: 4, Min: 1, Max: 256\n");
|
||||
printf(" (tweaking can help programs that hang or have audio glitches)\n");
|
||||
printf(" /gusdma n - force DMA interval to n us. Default: 0, Min: 0, Max: 255\n");
|
||||
printf(" Specifying 0 restores the GUS default behavior.\n");
|
||||
printf(" (increase to fix games with streaming audio like Doom)\n");
|
||||
printf(" /gus44k 1|0 - Fixed 44.1kHz output for all active voice #s [EXPERIMENTAL]\n");
|
||||
printf("\n");
|
||||
}
|
||||
fprintf(stderr, "\n\n");
|
||||
fprintf(stderr, " /? - show this message\n");
|
||||
fprintf(stderr, " /f fw.uf2 - program the PicoGUS with the firmware file fw.uf2\n");
|
||||
fprintf(stderr, " /j - enable USB joystick support\n");
|
||||
fprintf(stderr, " /v x - set volume of the wavetable header. Scale 0-100, Default: 100\n");
|
||||
fprintf(stderr, " (for PicoGUS v2.0 boards only)\n");
|
||||
fprintf(stderr, " /m x - change card mode to x (gus, sb, mpu, tandy, cms, joy)\n");
|
||||
fprintf(stderr, " /s - save settings to the card to persist on system boot\n");
|
||||
if (mode > GUS_MODE && mode < MOUSE_ONLY_MODE) {
|
||||
fprintf(stderr, "Sound Blaster/AdLib, MPU-401, Tandy, CMS modes only:\n");
|
||||
fprintf(stderr, " /p x - set the (hex) base port address of the emulated card. Defaults:\n");
|
||||
fprintf(stderr, " Sound Blaster: 220; MPU-401: 330; Tandy: 2C0; CMS: 220\n");
|
||||
// "................................................................................\n"
|
||||
if (mode == SB_MODE || print_all) {
|
||||
// "................................................................................\n"
|
||||
printf("Sound Blaster/AdLib mode settings:\n");
|
||||
printf(" /sbport x - set the base port of the Sound Blaster. Default: 220\n");
|
||||
printf(" /oplport x - set the base port of the OPL2/AdLib on the SB. Default: 388\n");
|
||||
printf(" /oplwait 1|0 - wait on OPL2 write. Can fix speed-sensitive early AdLib games\n");
|
||||
printf("\n");
|
||||
}
|
||||
if (mode == SB_MODE) {
|
||||
fprintf(stderr, " /o x - set the base address of the OPL2/AdLib on the SB. Default: 388\n");
|
||||
fprintf(stderr, " /w - wait on OPL2 data write. Can fix speed-sensitive early AdLib games\n");
|
||||
// "................................................................................\n"
|
||||
if (mode == MPU_MODE || print_all) {
|
||||
// "................................................................................\n"
|
||||
printf("MPU-401 mode settings:\n");
|
||||
printf(" /mpuport x - set the base port of the MPU-401. Default: 330\n");
|
||||
printf(" /mpudelay 1|0 - delay SYSEX (for rev.0 Roland MT-32)\n");
|
||||
printf(" /mpufake 1|0 - fake all notes off (for Roland RA-50)\n");
|
||||
printf("\n");
|
||||
}
|
||||
if (mode == MPU_MODE) {
|
||||
fprintf(stderr, "MPU-401 mode only:\n");
|
||||
fprintf(stderr, " /x - delay SYSEX (for rev.0 Roland MT-32)\n");
|
||||
fprintf(stderr, " /n - fake all notes off (for Roland RA-50)\n");
|
||||
// "................................................................................\n"
|
||||
if (mode == TANDY_MODE || print_all) {
|
||||
// "................................................................................\n"
|
||||
printf("Tandy mode settings:\n");
|
||||
printf(" /tandyport x - set the base port of the Tandy 3-voice. Default: 2C0\n");
|
||||
printf("\n");
|
||||
}
|
||||
if (mode == CMS_MODE || print_all) {
|
||||
// "................................................................................\n"
|
||||
printf("CMS mode settings:\n");
|
||||
printf(" /cmsport x - set the base port of the CMS. Default: 220\n");
|
||||
printf("\n");
|
||||
}
|
||||
if (mode == USB_MODE || print_all) {
|
||||
// "................................................................................\n"
|
||||
printf("Serial Mouse mode settings:\n");
|
||||
printf(" /mouseport n - set COM port of the mouse. Default: 2, Choices: 1, 2, 3, 4\n");
|
||||
printf(" /mouseproto n - set mouse protocol. Default: 2 (IntelliMouse)\n");
|
||||
printf(" 0 - Microsoft Mouse 2-button, 1 - Logitech 3-button\n");
|
||||
printf(" 2 - IntelliMouse 3-button + wheel, 3 - Mouse Systems 3-button\n");
|
||||
printf(" /mouserate n - set report rate in Hz. Default: 60, Min: 20, Max: 200\n");
|
||||
printf(" (increase for smoother cursor movement, decrease for lower CPU load)\n");
|
||||
printf(" /mousesen n - set mouse sensitivity (256 - 100%, 128 - 50%, 512 - 200%)\n");
|
||||
}
|
||||
/*
|
||||
if (mode == GUS_MODE) {
|
||||
fprintf(stderr, "GUS mode only:\n");
|
||||
fprintf(stderr, " /a n - set audio buffer to n samples. Default: 4, Min: 1, Max: 256\n");
|
||||
fprintf(stderr, " (tweaking this can help programs that hang or have audio glitches)\n");
|
||||
fprintf(stderr, " /d n - force DMA interval to n us. Default: 0, Min: 0, Max: 255\n");
|
||||
fprintf(stderr, " Specifying 0 restores the GUS default behavior.\n");
|
||||
fprintf(stderr, " (if games with streaming audio like Doom stutter, increase this)\n");
|
||||
fprintf(stderr, " /4 - Enable fixed 44.1kHz output for all active voice #s [EXPERIMENTAL]\n");
|
||||
fprintf(stderr, "The ULTRASND environment variable must be set in the following format:\n");
|
||||
fprintf(stderr, "\tset ULTRASND=xxx,y,n,z,n\n");
|
||||
fprintf(stderr, "Where xxx = port, y = DMA, z = IRQ. n is ignored.\n");
|
||||
fprintf(stderr, "Port is set on the card according to ULTRASND; DMA and IRQ configued via jumper.");
|
||||
// "................................................................................\n"
|
||||
}
|
||||
if (mode == MOUSE_ONLY_MODE) {
|
||||
fprintf(stderr, "Serial Mouse mode only:\n");
|
||||
fprintf(stderr, " /m n - set mouse protocol. Default: 2 (IntelliMouse)\n");
|
||||
fprintf(stderr, " 0 - Microsoft Mouse 2-button, 1 - Logitech 3-button\n");
|
||||
fprintf(stderr, " 2 - IntelliMouse 3-button + wheel, 3 - Mouse Systems 3-button\n");
|
||||
fprintf(stderr, " /r n - set report rate in Hz. Default: 60, Min: 20, Max: 200\n");
|
||||
fprintf(stderr, " (increase for smoother cursor movement, decrease for lower CPU load)\n");
|
||||
fprintf(stderr, " /s n - set mouse sensitivity (256 - 100%, 128 - 50%, 512 - 200%)\n");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
const char* mouse_protocol_str[] = {
|
||||
@@ -123,7 +106,7 @@ const char* mouse_protocol_str[] = {
|
||||
|
||||
void err_ultrasnd(char *argv0) {
|
||||
fprintf(stderr, "ERROR: no ULTRASND variable set or is malformed!\n");
|
||||
usage(argv0, GUS_MODE);
|
||||
usage(argv0, GUS_MODE, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -156,7 +139,7 @@ int init_gus(char *argv0) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
outp(CONTROL_PORT, 0x04); // Select port register
|
||||
outp(CONTROL_PORT, MODE_GUSPORT); // Select port register
|
||||
outpw(DATA_PORT_LOW, port); // Write port
|
||||
|
||||
// Detect if there's something GUS-like...
|
||||
@@ -185,7 +168,7 @@ int init_gus(char *argv0) {
|
||||
|
||||
void print_firmware_string(void) {
|
||||
outp(CONTROL_PORT, 0xCC); // Knock on the door...
|
||||
outp(CONTROL_PORT, 0x02); // Select firmware string register
|
||||
outp(CONTROL_PORT, MODE_FWSTRING); // Select firmware string register
|
||||
|
||||
char firmware_string[256] = {0};
|
||||
for (int i = 0; i < 255; ++i) {
|
||||
@@ -208,7 +191,7 @@ bool wait_for_read(const uint8_t value) {
|
||||
}
|
||||
|
||||
void write_settings(void) {
|
||||
outp(CONTROL_PORT, 0xE1); // Select save settings register
|
||||
outp(CONTROL_PORT, MODE_SAVE); // Select save settings register
|
||||
outp(DATA_PORT_HIGH, 0xff);
|
||||
printf("Settings saved to flash.\n");
|
||||
delay(100);
|
||||
@@ -218,7 +201,7 @@ void write_settings(void) {
|
||||
int reboot_to_firmware(const uint8_t value, const bool permanent) {
|
||||
outp(CONTROL_PORT, 0xCC); // Knock on the door...
|
||||
|
||||
outp(CONTROL_PORT, 0xE0); // Select firmware selection register
|
||||
outp(CONTROL_PORT, MODE_BOOTMODE); // Select firmware selection register
|
||||
outp(DATA_PORT_HIGH, value); // Send firmware number and permanent flag
|
||||
delay(100);
|
||||
|
||||
@@ -226,8 +209,8 @@ int reboot_to_firmware(const uint8_t value, const bool permanent) {
|
||||
if (permanent) {
|
||||
write_settings();
|
||||
}
|
||||
printf("Rebooting to fw: %s...\n", fwnames[value]);
|
||||
outp(CONTROL_PORT, 0xE2); // Select reboot register
|
||||
printf("Rebooting to fw: %s...\n", modenames[value]);
|
||||
outp(CONTROL_PORT, MODE_REBOOT); // Select reboot register
|
||||
outp(DATA_PORT_HIGH, 0xff);
|
||||
delay(100);
|
||||
|
||||
@@ -241,7 +224,7 @@ int reboot_to_firmware(const uint8_t value, const bool permanent) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int write_firmware(const char* fw_filename, uint8_t protocol) {
|
||||
int write_firmware(const char* fw_filename) {
|
||||
union {
|
||||
uint8_t buf[512];
|
||||
struct UF2_Block {
|
||||
@@ -265,6 +248,12 @@ int write_firmware(const char* fw_filename, uint8_t protocol) {
|
||||
return 10;
|
||||
}
|
||||
|
||||
outp(CONTROL_PORT, 0x01); // Select protocol version register
|
||||
uint8_t protocol = inp(DATA_PORT_HIGH);
|
||||
if (PICOGUS_PROTOCOL_VER != protocol && protocol < 3) {
|
||||
printf("Older fw protocol version %d detected, upgrading firmware in compatibility mode\n", protocol);
|
||||
}
|
||||
|
||||
uint32_t numBlocks = 1;
|
||||
for (uint32_t i = 0; i < numBlocks; ++i) {
|
||||
if (fread(uf2_buf.buf, 1, 512, fp) != 512) {
|
||||
@@ -282,7 +271,7 @@ int write_firmware(const char* fw_filename, uint8_t protocol) {
|
||||
|
||||
// Put card into programming mode
|
||||
outp(CONTROL_PORT, 0xCC); // Knock on the door...
|
||||
outp(CONTROL_PORT, 0xFF); // Select firmware programming mode
|
||||
outp(CONTROL_PORT, MODE_FLASH); // Select firmware programming mode
|
||||
// Wait a bit for 2nd core on Pico to restart
|
||||
delay(100);
|
||||
if (!wait_for_read(PICO_FIRMWARE_IDLE)) {
|
||||
@@ -316,13 +305,13 @@ int write_firmware(const char* fw_filename, uint8_t protocol) {
|
||||
fprintf(stderr, "\nERROR: Card is not in firmware writing mode?\n");
|
||||
return 15;
|
||||
}
|
||||
} else if (protocol == 2) {
|
||||
} else if (protocol > 1) {
|
||||
if (!wait_for_read(PICO_FIRMWARE_DONE)) {
|
||||
fprintf(stderr, "\nERROR: Card has written last firmware byte but is not done\n");
|
||||
return 15;
|
||||
}
|
||||
outp(CONTROL_PORT, 0xCC); // Knock on the door...
|
||||
outp(CONTROL_PORT, 0xFF); // Select firmware programming mode, which will reboot the card in DONE
|
||||
outp(CONTROL_PORT, MODE_FLASH); // Select firmware programming mode, which will reboot the card in DONE
|
||||
}
|
||||
}
|
||||
fprintf(stderr, ".");
|
||||
@@ -341,31 +330,44 @@ int write_firmware(const char* fw_filename, uint8_t protocol) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define process_bool_opt(option) \
|
||||
if (i + 1 >= argc) { \
|
||||
usage(argv[0], mode, false); \
|
||||
return 255; \
|
||||
} \
|
||||
e = sscanf(argv[++i], "%1[01]", tmp_arg); \
|
||||
if (e != 1) { \
|
||||
usage(argv[0], mode, false); \
|
||||
return 5; \
|
||||
} \
|
||||
option = (tmp_arg[0] == 1) ? 1 : 0;
|
||||
|
||||
|
||||
#define process_port_opt(option) \
|
||||
if (i + 1 >= argc) { \
|
||||
usage(argv[0], mode, false); \
|
||||
return 255; \
|
||||
} \
|
||||
e = sscanf(argv[++i], "%hx", &option); \
|
||||
if (e != 1 || option > 0x3ffu) { \
|
||||
usage(argv[0], mode, false); \
|
||||
return 4; \
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
int e;
|
||||
unsigned short buffer_size = 0;
|
||||
unsigned short dma_interval = 0;
|
||||
uint8_t force_44k = 0;
|
||||
uint16_t port_override = 0;
|
||||
uint16_t opl_port_override = 0;
|
||||
uint8_t wt_volume;
|
||||
uint8_t enable_joystick = 0;
|
||||
uint8_t wtvol;
|
||||
char fw_filename[256] = {0};
|
||||
card_mode_t mode;
|
||||
uint8_t mpu_delaysysex = 0;
|
||||
uint8_t mpu_fakeallnotesoff = 0;
|
||||
uint8_t enable_joystick = 0;
|
||||
uint8_t adlib_wait = 0;
|
||||
char mode_name[8] = {0};
|
||||
int fw_num = 8;
|
||||
bool permanent = false;
|
||||
|
||||
uint8_t mouse_protocol = 255, mouse_report_rate = 0;
|
||||
int16_t mouse_sensitivity = 0;
|
||||
|
||||
banner();
|
||||
// Get magic value from port on PicoGUS that is not on real GUS
|
||||
outp(CONTROL_PORT, 0xCC); // Knock on the door...
|
||||
outp(CONTROL_PORT, 0x00); // Select magic string register
|
||||
outp(CONTROL_PORT, MODE_MAGIC); // Select magic string register
|
||||
if (inp(DATA_PORT_HIGH) != 0xDD) {
|
||||
err_pigus();
|
||||
return 99;
|
||||
@@ -373,168 +375,203 @@ int main(int argc, char* argv[]) {
|
||||
printf("PicoGUS detected: ");
|
||||
print_firmware_string();
|
||||
|
||||
outp(CONTROL_PORT, 0x03); // Select mode register
|
||||
mode = inp(DATA_PORT_HIGH);
|
||||
|
||||
// Default wavetable volume to 100 in MPU mode, 0 otherwise
|
||||
wt_volume = (mode == MPU_MODE) ? 100 : 0;
|
||||
|
||||
int i = 1;
|
||||
// /flash option is special and can work across protocol versions, so if it's specified, that's all we do
|
||||
while (i < argc) {
|
||||
if (stricmp(argv[i], "/?") == 0) {
|
||||
usage(argv[0], mode);
|
||||
return 0;
|
||||
} else if (stricmp(argv[i], "/j") == 0) {
|
||||
enable_joystick = 1;
|
||||
} else if (stricmp(argv[i], "/m") == 0) {
|
||||
if (stricmp(argv[i], "/flash") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%7s", mode_name);
|
||||
if (e != 1) {
|
||||
usage(argv[0], mode);
|
||||
return 5;
|
||||
}
|
||||
} else if (stricmp(argv[i], "/4") == 0) {
|
||||
force_44k = 1;
|
||||
} else if (stricmp(argv[i], "/a") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%hu", &buffer_size);
|
||||
if (e != 1 || buffer_size < 1 || buffer_size > 256) {
|
||||
usage(argv[0], mode);
|
||||
return 3;
|
||||
}
|
||||
} else if (stricmp(argv[i], "/d") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%hu", &dma_interval);
|
||||
if (e != 1 || dma_interval > 255) {
|
||||
usage(argv[0], mode);
|
||||
return 4;
|
||||
}
|
||||
} else if (stricmp(argv[i], "/p") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%hx", &port_override);
|
||||
if (e != 1 || port_override > 0x3ffu) {
|
||||
usage(argv[0], mode);
|
||||
return 4;
|
||||
}
|
||||
} else if (stricmp(argv[i], "/o") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%hx", &opl_port_override);
|
||||
if (e != 1 || opl_port_override > 0x3ffu) {
|
||||
usage(argv[0], mode);
|
||||
return 4;
|
||||
}
|
||||
} else if (stricmp(argv[i], "/w") == 0) {
|
||||
adlib_wait = 1;
|
||||
} else if (stricmp(argv[i], "/v") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%hu", &wt_volume);
|
||||
if (e != 1 || wt_volume > 100) {
|
||||
usage(argv[0], mode);
|
||||
return 4;
|
||||
}
|
||||
} else if (stricmp(argv[i], "/x") == 0) {
|
||||
mpu_delaysysex = 1;
|
||||
} else if (stricmp(argv[i], "/s") == 0) {
|
||||
if (mode == MPU_MODE) {
|
||||
mpu_delaysysex = 1;
|
||||
} else {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%hi", &mouse_sensitivity);
|
||||
if (e != 1) {
|
||||
usage(argv[0], mode);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
} else if (stricmp(argv[i], "/n") == 0) {
|
||||
mpu_fakeallnotesoff = 1;
|
||||
} else if (stricmp(argv[i], "/f") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode);
|
||||
usage(argv[0], INVALID_MODE, false);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%255s", fw_filename);
|
||||
if (e != 1) {
|
||||
usage(argv[0], mode);
|
||||
usage(argv[0], INVALID_MODE, false);
|
||||
return 5;
|
||||
}
|
||||
} else if (stricmp(argv[i], "/s") == 0) {
|
||||
permanent = true;
|
||||
} else if (stricmp(argv[i], "/m") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%hu", &mouse_protocol);
|
||||
if (e != 1 || mouse_protocol > 3) {
|
||||
usage(argv[0], mode);
|
||||
return 4;
|
||||
}
|
||||
} else if (stricmp(argv[i], "/r") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%hu", &mouse_report_rate);
|
||||
if (e != 1 || mouse_report_rate < 20 || mouse_report_rate > 200) {
|
||||
usage(argv[0], mode);
|
||||
return 4;
|
||||
}
|
||||
return write_firmware(fw_filename);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
outp(CONTROL_PORT, 0x01); // Select protocol version register
|
||||
uint8_t protocol_got = inp(DATA_PORT_HIGH);
|
||||
if (PICOGUS_PROTOCOL_VER != protocol_got) {
|
||||
if (fw_filename[0] && protocol_got == 1) {
|
||||
printf("Older fw protocol version 1 detected, upgrading firmware in compatibility mode\n");
|
||||
} else {
|
||||
err_protocol(PICOGUS_PROTOCOL_VER, protocol_got);
|
||||
return 97;
|
||||
}
|
||||
err_protocol(PICOGUS_PROTOCOL_VER, protocol_got);
|
||||
return 97;
|
||||
}
|
||||
|
||||
if (fw_filename[0]) {
|
||||
return write_firmware(fw_filename, protocol_got);
|
||||
outp(CONTROL_PORT, MODE_MODE); // Select mode register
|
||||
mode = inp(DATA_PORT_HIGH);
|
||||
|
||||
char tmp_arg[2];
|
||||
uint16_t tmp_uint16;
|
||||
uint8_t tmp_uint8;
|
||||
i = 1;
|
||||
while (i < argc) {
|
||||
// global options /////////////////////////////////////////////////////////////////
|
||||
if (stricmp(argv[i], "/?") == 0) {
|
||||
usage(argv[0], mode, false);
|
||||
return 0;
|
||||
} else if (stricmp(argv[i], "/??") == 0) {
|
||||
usage(argv[0], mode, true);
|
||||
return 0;
|
||||
} else if (stricmp(argv[i], "/joy") == 0) {
|
||||
process_bool_opt(tmp_uint8);
|
||||
outp(CONTROL_PORT, MODE_JOYEN); // Select joystick enable register
|
||||
outp(DATA_PORT_HIGH, tmp_uint8);
|
||||
} else if (stricmp(argv[i], "/mode") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode, false);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%7s", mode_name);
|
||||
if (e != 1) {
|
||||
usage(argv[0], mode, false);
|
||||
return 5;
|
||||
}
|
||||
} else if (stricmp(argv[i], "/wtvol") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode, false);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%hhu", &tmp_uint8);
|
||||
if (e != 1 || tmp_uint8 > 100) {
|
||||
usage(argv[0], mode, false);
|
||||
return 4;
|
||||
}
|
||||
outp(CONTROL_PORT, MODE_WTVOL); // Select wavetable volume register
|
||||
outp(DATA_PORT_HIGH, tmp_uint8); // Write volume
|
||||
} else if (stricmp(argv[i], "/save") == 0) {
|
||||
permanent = true;
|
||||
} else if (stricmp(argv[i], "/defaults") == 0) {
|
||||
outp(CONTROL_PORT, MODE_DEFAULTS); // Select defaults register
|
||||
outp(DATA_PORT_HIGH, 0xff); // Write volume
|
||||
// GUS options /////////////////////////////////////////////////////////////////
|
||||
} else if (stricmp(argv[i], "/gus44k") == 0) {
|
||||
process_bool_opt(tmp_uint8);
|
||||
outp(CONTROL_PORT, MODE_GUS44K); // Select force 44k buffer
|
||||
outp(DATA_PORT_HIGH, tmp_uint8);
|
||||
} else if (stricmp(argv[i], "/gusbuf") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode, false);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%hhu", &tmp_uint8);
|
||||
if (e != 1 || tmp_uint8 < 1) {
|
||||
usage(argv[0], mode, false);
|
||||
return 3;
|
||||
}
|
||||
outp(CONTROL_PORT, MODE_GUSBUF); // Select audio buffer register
|
||||
outp(DATA_PORT_HIGH, (unsigned char)(tmp_uint8 - 1));
|
||||
} else if (stricmp(argv[i], "/gusdma") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode, false);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%hhu", &tmp_uint8);
|
||||
if (e != 1) {
|
||||
usage(argv[0], mode, false);
|
||||
return 4;
|
||||
}
|
||||
outp(CONTROL_PORT, MODE_GUSDMA); // Select DMA interval register
|
||||
outp(DATA_PORT_HIGH, tmp_uint8);
|
||||
} else if (stricmp(argv[i], "/gusport") == 0) {
|
||||
process_port_opt(tmp_uint16);
|
||||
outp(CONTROL_PORT, MODE_GUSPORT); // Select GUS port register
|
||||
outpw(DATA_PORT_LOW, tmp_uint16); // Write port
|
||||
// SB options /////////////////////////////////////////////////////////////////
|
||||
} else if (stricmp(argv[i], "/sbport") == 0) {
|
||||
process_port_opt(tmp_uint16);
|
||||
outp(CONTROL_PORT, MODE_SBPORT); // Select SB port register
|
||||
outpw(DATA_PORT_LOW, tmp_uint16); // Write port
|
||||
} else if (stricmp(argv[i], "/oplport") == 0) {
|
||||
process_port_opt(tmp_uint16);
|
||||
outp(CONTROL_PORT, MODE_OPLPORT); // Select OPL port register
|
||||
outpw(DATA_PORT_LOW, tmp_uint16); // Write port
|
||||
} else if (stricmp(argv[i], "/oplwait") == 0) {
|
||||
process_bool_opt(tmp_uint8);
|
||||
outp(CONTROL_PORT, MODE_OPLWAIT); // Select Adlib wait register
|
||||
outp(DATA_PORT_HIGH, tmp_uint8); // Write sysex delay and fake all notes off settings
|
||||
// MPU options /////////////////////////////////////////////////////////////////
|
||||
} else if (stricmp(argv[i], "/mpuport") == 0) {
|
||||
process_port_opt(tmp_uint16);
|
||||
outp(CONTROL_PORT, MODE_MPUPORT); // Select MPU port register
|
||||
outpw(DATA_PORT_LOW, tmp_uint16); // Write port
|
||||
} else if (stricmp(argv[i], "/mpudelay") == 0) {
|
||||
process_bool_opt(tmp_uint8);
|
||||
outp(CONTROL_PORT, MODE_MPUDELAY); // Select MPU sysex delay register
|
||||
outp(DATA_PORT_HIGH, tmp_uint8);
|
||||
} else if (stricmp(argv[i], "/mpufake") == 0) {
|
||||
process_bool_opt(tmp_uint8);
|
||||
outp(CONTROL_PORT, MODE_MPUFAKE); // Select MPU fake all notes off register
|
||||
outp(DATA_PORT_HIGH, tmp_uint8);
|
||||
// Tandy options /////////////////////////////////////////////////////////////////
|
||||
} else if (stricmp(argv[i], "/tandyport") == 0) {
|
||||
process_port_opt(tmp_uint16);
|
||||
outp(CONTROL_PORT, MODE_TANDYPORT); // Select Tandy port register
|
||||
outpw(DATA_PORT_LOW, tmp_uint16); // Write port
|
||||
// CMS options /////////////////////////////////////////////////////////////////
|
||||
} else if (stricmp(argv[i], "/cmsport") == 0) {
|
||||
process_port_opt(tmp_uint16);
|
||||
outp(CONTROL_PORT, MODE_CMSPORT); // Select CMS port register
|
||||
outpw(DATA_PORT_LOW, tmp_uint16); // Write port
|
||||
// Mouse options /////////////////////////////////////////////////////////////////
|
||||
} else if (stricmp(argv[i], "/mousesen") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode, false);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%hi", &tmp_uint16);
|
||||
if (e != 1) {
|
||||
usage(argv[0], mode, false);
|
||||
return 4;
|
||||
}
|
||||
outp(CONTROL_PORT, MODE_MOUSESEN); // Select mouse sensitivity register
|
||||
outpw(DATA_PORT_LOW, tmp_uint16);
|
||||
} else if (stricmp(argv[i], "/mouseproto") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode, false);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%hhu", &tmp_uint8);
|
||||
if (e != 1 || tmp_uint8 > 3) {
|
||||
usage(argv[0], mode, false);
|
||||
return 4;
|
||||
}
|
||||
outp(CONTROL_PORT, MODE_MOUSEPROTO);
|
||||
outp(DATA_PORT_HIGH, tmp_uint8);
|
||||
} else if (stricmp(argv[i], "/mouserate") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode, false);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%hhu", &tmp_uint8);
|
||||
if (e != 1 || tmp_uint8 < 20 || tmp_uint8 > 200) {
|
||||
usage(argv[0], mode, false);
|
||||
return 4;
|
||||
}
|
||||
outp(CONTROL_PORT, MODE_MOUSERATE);
|
||||
outp(DATA_PORT_HIGH, tmp_uint8);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
|
||||
if (mode_name[0]) {
|
||||
int i;
|
||||
for (i = 1; i < 8; ++i) {
|
||||
if (strnicmp(fwnames[i], mode_name, 7) == 0) {
|
||||
if (strnicmp(modenames[i], mode_name, 7) == 0) {
|
||||
fw_num = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == 8) {
|
||||
usage(argv[0], mode);
|
||||
usage(argv[0], mode, false);
|
||||
return 255;
|
||||
}
|
||||
return reboot_to_firmware(fw_num, permanent);
|
||||
}
|
||||
|
||||
outp(CONTROL_PORT, 0xf0); // Select hardware type register
|
||||
outp(CONTROL_PORT, MODE_HWTYPE); // Select hardware type register
|
||||
board_type_t board_type = inp(DATA_PORT_HIGH);
|
||||
if (board_type == PICO_BASED) {
|
||||
printf("Hardware: PicoGUS v1.x or PicoGUS Femto\n");
|
||||
@@ -545,121 +582,104 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
uint16_t port;
|
||||
uint16_t opl_port;
|
||||
if (mode != GUS_MODE && mode != MOUSE_ONLY_MODE) {
|
||||
if (port_override) {
|
||||
outp(CONTROL_PORT, 0x04); // Select port register
|
||||
outpw(DATA_PORT_LOW, port_override); // Write port
|
||||
}
|
||||
outp(CONTROL_PORT, MODE_JOYEN); // Select joystick enable register
|
||||
tmp_uint8 = inp(DATA_PORT_HIGH);
|
||||
printf("USB joystick support %s\n", tmp_uint8 ? "enabled" : "disabled");
|
||||
|
||||
outp(CONTROL_PORT, 0x04); // Select port register
|
||||
port = inpw(DATA_PORT_LOW); // Get port
|
||||
if (mode == SB_MODE) {
|
||||
if (opl_port_override) {
|
||||
outp(CONTROL_PORT, 0x05); // Select OPL port register
|
||||
outpw(DATA_PORT_LOW, opl_port_override); // Write port
|
||||
}
|
||||
outp(CONTROL_PORT, 0x05); // Select OPL port register
|
||||
opl_port = inpw(DATA_PORT_LOW); // Get port
|
||||
}
|
||||
}
|
||||
|
||||
if (mode != MOUSE_ONLY_MODE) {
|
||||
outp(CONTROL_PORT, 0x0f); // Select joystick enable register
|
||||
outp(DATA_PORT_HIGH, enable_joystick);
|
||||
printf("USB joystick support %s\n", enable_joystick ? "enabled" : "disabled");
|
||||
}
|
||||
// Get joystick status (connected, joystick type, etc.)
|
||||
|
||||
if (board_type == PICOGUS_2) {
|
||||
outp(CONTROL_PORT, 0x20); // Select wavetable volume register
|
||||
outp(DATA_PORT_HIGH, wt_volume); // Write volume
|
||||
printf("Wavetable volume set to %u\n", wt_volume);
|
||||
outp(CONTROL_PORT, MODE_WTVOL); // Select wavetable volume register
|
||||
outp(DATA_PORT_HIGH, wtvol); // Write volume
|
||||
printf("Wavetable volume set to %u\n", wtvol);
|
||||
}
|
||||
|
||||
switch(mode) {
|
||||
case GUS_MODE:
|
||||
init_gus(argv[0]);
|
||||
if (!buffer_size) {
|
||||
buffer_size = 4;
|
||||
}
|
||||
outp(CONTROL_PORT, 0x10); // Select audio buffer register
|
||||
outp(DATA_PORT_HIGH, (unsigned char)(buffer_size - 1));
|
||||
printf("Audio buffer size set to %u samples\n", buffer_size);
|
||||
printf("GUS settings: ");
|
||||
outp(CONTROL_PORT, MODE_GUSBUF); // Select audio buffer register
|
||||
tmp_uint16 = inp(DATA_PORT_HIGH) + 1;
|
||||
printf("Audio buffer: %u samples; ", tmp_uint16);
|
||||
|
||||
outp(CONTROL_PORT, 0x11); // Select DMA interval register
|
||||
outp(DATA_PORT_HIGH, dma_interval);
|
||||
if (dma_interval == 0) {
|
||||
printf("DMA interval set to default behavior\n");
|
||||
outp(CONTROL_PORT, MODE_GUSDMA); // Select DMA interval register
|
||||
tmp_uint8 = inp(DATA_PORT_HIGH);
|
||||
if (tmp_uint8 == 0) {
|
||||
printf("DMA interval: default; ");
|
||||
} else {
|
||||
printf("DMA interval forced to %u us\n", dma_interval);
|
||||
printf("DMA interval: %u us; ", tmp_uint8);
|
||||
}
|
||||
|
||||
outp(CONTROL_PORT, 0x12); // Select force 44k buffer
|
||||
outp(DATA_PORT_HIGH, force_44k);
|
||||
if (force_44k) {
|
||||
printf("Fixed 44.1kHz output enabled (EXPERIMENTAL)\n");
|
||||
outp(CONTROL_PORT, MODE_GUS44K); // Select force 44k buffer
|
||||
tmp_uint8 = inp(DATA_PORT_HIGH);
|
||||
if (tmp_uint8) {
|
||||
printf("Fixed 44.1kHz rate\n");
|
||||
} else {
|
||||
printf("Variable sample rate\n");
|
||||
}
|
||||
|
||||
outp(CONTROL_PORT, 0x04); // Select port register
|
||||
port = inpw(DATA_PORT_LOW); // Get port
|
||||
printf("Running in GUS mode on port %x\n", port);
|
||||
outp(CONTROL_PORT, MODE_GUSPORT); // Select port register
|
||||
tmp_uint16 = inpw(DATA_PORT_LOW); // Get port
|
||||
printf("Running in GUS mode on port %x\n", tmp_uint16);
|
||||
break;
|
||||
/* AdLib mode is coming back...
|
||||
case ADLIB_MODE:
|
||||
printf("Running in AdLib/OPL2 mode on port %x\n", port);
|
||||
outp(CONTROL_PORT, MODE_OPLPORT); // Select port register
|
||||
tmp_uint16 = inpw(DATA_PORT_LOW); // Get port
|
||||
printf("Running in AdLib/OPL2 mode on port %x\n", tmp_uint16);
|
||||
break;
|
||||
*/
|
||||
case MPU_MODE:
|
||||
printf("MPU-401 sysex delay: %s, fake all notes off: %s\n", mpu_delaysysex ? "on" : "off", mpu_fakeallnotesoff ? "on" : "off");
|
||||
outp(CONTROL_PORT, 0x21); // Select MPU settings register
|
||||
outp(DATA_PORT_HIGH, mpu_delaysysex | (mpu_fakeallnotesoff << 1)); // Write sysex delay and fake all notes off settings
|
||||
printf("Running in MPU-401 mode on port %x\n", port);
|
||||
outp(CONTROL_PORT, MODE_MPUDELAY); // Select force 44k buffer
|
||||
tmp_uint8 = inp(DATA_PORT_HIGH);
|
||||
printf("MPU-401 sysex delay: %s, ", tmp_uint8 ? "on" : "off");
|
||||
outp(CONTROL_PORT, MODE_MPUFAKE); // Select force 44k buffer
|
||||
tmp_uint8 = inp(DATA_PORT_HIGH);
|
||||
printf("fake all notes off: %s\n", tmp_uint8 ? "on" : "off");
|
||||
outp(CONTROL_PORT, MODE_MPUPORT); // Select port register
|
||||
tmp_uint16 = inpw(DATA_PORT_LOW); // Get port
|
||||
printf("Running in MPU-401 mode on port %x\n", tmp_uint16);
|
||||
break;
|
||||
case TANDY_MODE:
|
||||
printf("Running in Tandy 3-voice mode on port %x\n", port);
|
||||
outp(CONTROL_PORT, MODE_TANDYPORT); // Select port register
|
||||
tmp_uint16 = inpw(DATA_PORT_LOW); // Get port
|
||||
printf("Running in Tandy 3-voice mode on port %x\n", tmp_uint16);
|
||||
break;
|
||||
case CMS_MODE:
|
||||
printf("Running in CMS/Game Blaster mode on port %x\n", port);
|
||||
outp(CONTROL_PORT, MODE_CMSPORT); // Select port register
|
||||
tmp_uint16 = inpw(DATA_PORT_LOW); // Get port
|
||||
printf("Running in CMS/Game Blaster mode on port %x\n", tmp_uint16);
|
||||
break;
|
||||
case SB_MODE:
|
||||
outp(CONTROL_PORT, 0x30); // Select Adlib wait register
|
||||
outp(DATA_PORT_HIGH, adlib_wait); // Write sysex delay and fake all notes off settings
|
||||
printf("Running in Sound Blaster 2.0 mode on port %x (AdLib port %x%s)\n",
|
||||
port, opl_port, adlib_wait ? ", wait on" : "");
|
||||
outp(CONTROL_PORT, MODE_OPLPORT); // Select port register
|
||||
tmp_uint16 = inpw(DATA_PORT_LOW); // Get port
|
||||
printf("Running in Sound Blaster 2.0 mode on port %x ", tmp_uint16);
|
||||
outp(CONTROL_PORT, MODE_OPLPORT); // Select port register
|
||||
tmp_uint16 = inpw(DATA_PORT_LOW); // Get port
|
||||
printf("(AdLib port %x", tmp_uint16);
|
||||
outp(CONTROL_PORT, MODE_OPLWAIT); // Select Adlib wait register
|
||||
tmp_uint8 = inp(DATA_PORT_HIGH);
|
||||
printf("%s)\n", tmp_uint8 ? ", wait on" : "");
|
||||
break;
|
||||
case JOYSTICK_ONLY_MODE:
|
||||
printf("Running in Joystick exclusive mode on port 201\n");
|
||||
case MOUSE_ONLY_MODE:
|
||||
if (port_override) {
|
||||
outp(CONTROL_PORT, 0x40); // Select port register
|
||||
outpw(DATA_PORT_LOW, port_override); // Write port
|
||||
}
|
||||
outp(CONTROL_PORT, 0x40); // Select port register
|
||||
port = inpw(DATA_PORT_LOW); // Get port
|
||||
case USB_MODE:
|
||||
outp(CONTROL_PORT, MODE_MOUSEPORT); // Select port register
|
||||
tmp_uint16 = inpw(DATA_PORT_LOW); // Get port
|
||||
printf("Running in Serial Mouse exclusive mode on port %x\n", tmp_uint16);
|
||||
|
||||
outp(CONTROL_PORT, 0x41);
|
||||
if (mouse_protocol != 255)
|
||||
outp(DATA_PORT_HIGH, mouse_protocol);
|
||||
else
|
||||
mouse_protocol = inp(DATA_PORT_HIGH);
|
||||
outp(CONTROL_PORT, MODE_MOUSERATE);
|
||||
tmp_uint8 = inp(DATA_PORT_HIGH);
|
||||
printf("Mouse report rate: %d Hz, ", tmp_uint8);
|
||||
|
||||
outp(CONTROL_PORT, 0x42);
|
||||
if (mouse_report_rate)
|
||||
outp(DATA_PORT_HIGH, mouse_report_rate);
|
||||
else
|
||||
mouse_report_rate = inp(DATA_PORT_HIGH);
|
||||
outp(CONTROL_PORT, MODE_MOUSEPROTO);
|
||||
tmp_uint8 = inp(DATA_PORT_HIGH);
|
||||
printf("protocol: %s\n", mouse_protocol_str[tmp_uint8]);
|
||||
|
||||
outp(CONTROL_PORT, 0x43);
|
||||
if (mouse_sensitivity)
|
||||
outpw(DATA_PORT_LOW, mouse_sensitivity);
|
||||
else
|
||||
mouse_sensitivity = inpw(DATA_PORT_LOW);
|
||||
|
||||
printf("Running in Serial Mouse exclusive mode on port %x\n", port);
|
||||
printf("Mouse report rate: %d Hz, protocol: %s\n", mouse_report_rate, mouse_protocol_str[mouse_protocol]);
|
||||
printf("Mouse sensitivity: %d (%d.%02d)\n", mouse_sensitivity, (mouse_sensitivity >> 8), ((mouse_sensitivity & 0xFF) * 100) >> 8);
|
||||
outp(CONTROL_PORT, MODE_MOUSESEN);
|
||||
tmp_uint16 = inpw(DATA_PORT_LOW);
|
||||
printf("Mouse sensitivity: %d (%d.%02d)\n", tmp_uint16, (tmp_uint16 >> 8), ((tmp_uint16 & 0xFF) * 100) >> 8);
|
||||
break;
|
||||
default:
|
||||
printf("Running in unknown mode on port %x (maybe upgrade pgusinit?)\n", port);
|
||||
printf("Running in unknown mode (maybe upgrade pgusinit?)\n");
|
||||
break;
|
||||
}
|
||||
printf("PicoGUS initialized!\n");
|
||||
|
||||
+47
-16
@@ -93,9 +93,13 @@ function(config_target TARGET_NAME MULTIFW)
|
||||
set_linker_script(${TARGET_NAME} ${CMAKE_BINARY_DIR}/${TARGET_NAME}.ld)
|
||||
endif()
|
||||
|
||||
if(USB_JOYSTICK OR USB_MOUSE)
|
||||
set(USB_STACK TRUE)
|
||||
endif()
|
||||
if (USB_STACK)
|
||||
# USB stack common stuff
|
||||
target_link_libraries(picogus tinyusb_host)
|
||||
target_link_libraries(${TARGET_NAME} tinyusb_host)
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE USB_STACK=1)
|
||||
endif()
|
||||
if(USB_JOYSTICK)
|
||||
# Joystick stuff
|
||||
@@ -107,9 +111,9 @@ function(config_target TARGET_NAME MULTIFW)
|
||||
endif()
|
||||
if (USB_MOUSE)
|
||||
# USB Mouse stuff
|
||||
target_sources(picogus PRIVATE mouse/mouse_hid.c)
|
||||
target_include_directories(picogus PUBLIC ${CMAKE_CURRENT_LIST_DIR}/mouse)
|
||||
target_compile_definitions(picogus PRIVATE USB_MOUSE=1)
|
||||
target_sources(${TARGET_NAME} PRIVATE mouse/mouse_hid.c)
|
||||
target_include_directories(${TARGET_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/mouse)
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE USB_MOUSE=1)
|
||||
endif()
|
||||
|
||||
target_sources(${TARGET_NAME} PRIVATE M62429/M62429.cpp)
|
||||
@@ -131,10 +135,7 @@ function(config_target TARGET_NAME MULTIFW)
|
||||
pico_add_extra_outputs(${TARGET_NAME})
|
||||
endfunction()
|
||||
|
||||
if(USB_JOYSTICK)
|
||||
# Joystick stuff
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/tusb_xinput)
|
||||
endif()
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/tusb_xinput)
|
||||
add_subdirectory(rp2040-psram)
|
||||
add_subdirectory(opl)
|
||||
|
||||
@@ -142,6 +143,7 @@ add_subdirectory(opl)
|
||||
################################################################################
|
||||
# Build GUS firmware
|
||||
function(build_gus TARGET_NAME MULTIFW)
|
||||
set(USB_JOYSTICK 1)
|
||||
config_target(${TARGET_NAME} ${MULTIFW})
|
||||
pico_set_program_name(${TARGET_NAME} "picogus-gus")
|
||||
target_sources(${TARGET_NAME} PRIVATE gusplay.cpp pico_pic.c isa_dma.c)
|
||||
@@ -175,13 +177,14 @@ endfunction()
|
||||
################################################################################
|
||||
# Build SB firmware
|
||||
function(build_sb TARGET_NAME MULTIFW)
|
||||
set(USB_JOYSTICK 1)
|
||||
config_target(${TARGET_NAME} ${MULTIFW})
|
||||
pico_set_program_name(${TARGET_NAME} "picogus-sb")
|
||||
target_sources(${TARGET_NAME} PRIVATE sbdsp.cpp sbplay.cpp pico_pic.c isa_dma.c)
|
||||
target_link_libraries(${TARGET_NAME} opl)
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE
|
||||
SOUND_SB=1
|
||||
# SOUND_OPL=1
|
||||
SOUND_OPL=1
|
||||
SOUND_DSP=1
|
||||
USE_ALARM=1
|
||||
USE_EMU8950_OPL=1
|
||||
@@ -194,9 +197,31 @@ function(build_sb TARGET_NAME MULTIFW)
|
||||
pico_enable_stdio_semihosting(${TARGET_NAME} 0)
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
# Build AdLib firmware
|
||||
function(build_adlib TARGET_NAME MULTIFW)
|
||||
set(USB_JOYSTICK 1)
|
||||
set(USB_MOUSE 1)
|
||||
config_target(${TARGET_NAME} ${MULTIFW})
|
||||
pico_set_program_name(${TARGET_NAME} "picogus-sb")
|
||||
target_sources(${TARGET_NAME} PRIVATE sbplay.cpp)
|
||||
target_link_libraries(${TARGET_NAME} opl)
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE
|
||||
SOUND_OPL=1
|
||||
USE_ALARM=1
|
||||
USE_EMU8950_OPL=1
|
||||
EMU8950_ASM=1
|
||||
# PICOW=1
|
||||
)
|
||||
pico_enable_stdio_uart(${TARGET_NAME} 1)
|
||||
pico_enable_stdio_usb(${TARGET_NAME} 0)
|
||||
pico_enable_stdio_semihosting(${TARGET_NAME} 0)
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
# Build MPU firmware
|
||||
function(build_mpu TARGET_NAME MULTIFW)
|
||||
set(USB_JOYSTICK 1)
|
||||
config_target(${TARGET_NAME} ${MULTIFW})
|
||||
pico_set_program_name(${TARGET_NAME} "picogus-mpu401")
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE
|
||||
@@ -221,6 +246,8 @@ endfunction()
|
||||
################################################################################
|
||||
# Build Tandy firmware
|
||||
function(build_tandy TARGET_NAME MULTIFW)
|
||||
set(USB_JOYSTICK 1)
|
||||
set(USB_MOUSE 1)
|
||||
config_target(${TARGET_NAME} ${MULTIFW})
|
||||
pico_set_program_name(${TARGET_NAME} "picogus-tandy")
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE
|
||||
@@ -240,6 +267,8 @@ endfunction()
|
||||
################################################################################
|
||||
# Build CMS firmware
|
||||
function(build_cms TARGET_NAME MULTIFW)
|
||||
set(USB_JOYSTICK 1)
|
||||
set(USB_MOUSE 1)
|
||||
config_target(${TARGET_NAME} ${MULTIFW})
|
||||
pico_set_program_name(${TARGET_NAME} "picogus-cms")
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE
|
||||
@@ -258,20 +287,16 @@ endfunction()
|
||||
################################################################################
|
||||
# Build USB-only firmware (joystick + mouse support)
|
||||
function(build_usb TARGET_NAME MULTIFW)
|
||||
config_target(${TARGET_NAME} ${MULTIFW})
|
||||
pico_set_program_name(${TARGET_NAME} "picogus-usb")
|
||||
set(USB_STACK 1)
|
||||
set(USB_JOYSTICK 1)
|
||||
set(USB_MOUSE 1)
|
||||
config_target(${TARGET_NAME} ${MULTIFW})
|
||||
pico_set_program_name(${TARGET_NAME} "picogus-usb")
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE
|
||||
USB_JOYSTICK_ONLY=1
|
||||
USB_MOUSE_ONLY=1
|
||||
USB_ONLY=1
|
||||
)
|
||||
|
||||
target_sources(${TARGET_NAME} PRIVATE
|
||||
usbplay.cpp
|
||||
pico_pic.c
|
||||
mouseplay.cpp
|
||||
mouse/8250uart.cpp
|
||||
mouse/sermouse.cpp
|
||||
)
|
||||
@@ -337,6 +362,9 @@ if(PROJECT_TYPE STREQUAL "MULTIFW")
|
||||
build_sb(pg-sb FALSE)
|
||||
build_sb(pg-sb-multifw TRUE)
|
||||
add_dependencies(pg-sb-multifw pg-sb generate_flash_firmware_h)
|
||||
build_adlib(pg-adlib FALSE)
|
||||
build_adlib(pg-adlib-multifw TRUE)
|
||||
add_dependencies(pg-adlib-multifw pg-adlib generate_flash_firmware_h)
|
||||
build_mpu(pg-mpu FALSE)
|
||||
build_mpu(pg-mpu-multifw TRUE)
|
||||
add_dependencies(pg-mpu-multifw pg-mpu generate_flash_firmware_h)
|
||||
@@ -383,6 +411,9 @@ elseif(PROJECT_TYPE STREQUAL "GUS")
|
||||
elseif(PROJECT_TYPE STREQUAL "SB")
|
||||
set(FW_TARGET pg-sb)
|
||||
build_sb(pg-sb FALSE)
|
||||
elseif(PROJECT_TYPE STREQUAL "ADLIB")
|
||||
set(FW_TARGET pg-adlib)
|
||||
build_sb(pg-adlib FALSE)
|
||||
elseif(PROJECT_TYPE STREQUAL "MPU")
|
||||
set(FW_TARGET pg-mpu)
|
||||
build_mpu(pg-mpu FALSE)
|
||||
|
||||
+14
-3
@@ -19,9 +19,13 @@
|
||||
#include "pico/audio_i2s.h"
|
||||
#include "pico/flash.h"
|
||||
|
||||
#ifdef USB_JOYSTICK
|
||||
#ifdef USB_STACK
|
||||
#include "tusb.h"
|
||||
#endif
|
||||
#ifdef USB_MOUSE
|
||||
#include "mouse/8250uart.h"
|
||||
#include "mouse/sermouse.h"
|
||||
#endif
|
||||
|
||||
#ifdef MAME_CMS
|
||||
#include "saa1099/saa1099.h"
|
||||
@@ -80,7 +84,7 @@ void play_cms() {
|
||||
puts("starting core 1 CMS");
|
||||
flash_safe_execute_core_init();
|
||||
|
||||
#ifdef USB_JOYSTICK
|
||||
#ifdef USB_STACK
|
||||
// Init TinyUSB for joystick support
|
||||
tuh_init(BOARD_TUH_RHPORT);
|
||||
#endif
|
||||
@@ -172,9 +176,16 @@ void play_cms() {
|
||||
buffer->sample_count = buffer->max_sample_count;
|
||||
|
||||
give_audio_buffer(ap, buffer);
|
||||
#ifdef USB_JOYSTICK
|
||||
#ifdef USB_STACK
|
||||
// Service TinyUSB events
|
||||
tuh_task();
|
||||
#endif
|
||||
#ifdef USB_MOUSE
|
||||
// mouse task
|
||||
sermouse_core1_task();
|
||||
|
||||
// uart emulation task
|
||||
uartemu_core1_task();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
+8
-2
@@ -38,6 +38,12 @@ static const Settings defaultSettings = {
|
||||
},
|
||||
.Tandy = {
|
||||
.basePort = 0x2c0
|
||||
},
|
||||
.Mouse = {
|
||||
.basePort = 0xffff,
|
||||
.protocol = 0,
|
||||
.reportRate = 60,
|
||||
.sensitivity = 0x100
|
||||
}
|
||||
};
|
||||
|
||||
@@ -99,7 +105,7 @@ void saveSettings(const Settings* settings)
|
||||
*/
|
||||
}
|
||||
|
||||
void resetSettings(void)
|
||||
void getDefaultSettings(Settings* settings)
|
||||
{
|
||||
saveSettings(&defaultSettings);
|
||||
memcpy(settings, &defaultSettings, sizeof(Settings));
|
||||
}
|
||||
+8
-2
@@ -12,7 +12,7 @@ extern "C" {
|
||||
|
||||
// Settings struct has generous padding for future settings by aligning to 4 bytes
|
||||
typedef struct Settings {
|
||||
uint32_t magic; // should be "pgus" in ascii (0x7069636F)
|
||||
uint32_t magic; // should be "pgus" in ascii (0x70677573)
|
||||
uint8_t version;
|
||||
uint8_t startupMode;
|
||||
struct {
|
||||
@@ -43,12 +43,18 @@ typedef struct Settings {
|
||||
struct {
|
||||
uint16_t basePort;
|
||||
} Tandy;
|
||||
struct {
|
||||
uint16_t basePort;
|
||||
uint8_t protocol;
|
||||
uint8_t reportRate;
|
||||
int16_t sensitivity;
|
||||
} Mouse;
|
||||
} Settings;
|
||||
|
||||
|
||||
void loadSettings(Settings* settings);
|
||||
void saveSettings(const Settings* settings);
|
||||
void resetSettings(void);
|
||||
void getDefaultSettings(Settings* settings);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+3
-3
@@ -21,7 +21,7 @@
|
||||
#include "pico_pic.h"
|
||||
#endif
|
||||
|
||||
#ifdef USB_JOYSTICK
|
||||
#ifdef USB_STACK
|
||||
#include "tusb.h"
|
||||
#endif
|
||||
|
||||
@@ -121,7 +121,7 @@ void play_gus() {
|
||||
#endif
|
||||
#endif
|
||||
GUS_Setup();
|
||||
#ifdef USB_JOYSTICK
|
||||
#ifdef USB_STACK
|
||||
// Init TinyUSB for joystick support
|
||||
tuh_init(BOARD_TUH_RHPORT);
|
||||
#endif
|
||||
@@ -156,7 +156,7 @@ void play_gus() {
|
||||
*/
|
||||
// gpio_xor_mask(1u << PICO_DEFAULT_LED_PIN);
|
||||
give_audio_buffer(ap, buffer);
|
||||
#ifdef USB_JOYSTICK
|
||||
#ifdef USB_STACK
|
||||
// Service TinyUSB events
|
||||
tuh_task();
|
||||
#endif
|
||||
|
||||
@@ -95,7 +95,7 @@ static void sermouse_send_id() {
|
||||
// --------------------------
|
||||
|
||||
// inititalization
|
||||
uint32_t sermouse_init() {
|
||||
uint32_t sermouse_init(uint8_t protocol, uint8_t report_rate_hz, int16_t sensitivity) {
|
||||
// clear mouse state
|
||||
mouse_state.state = SERMOUSE_STATE_RESET;
|
||||
mouse_state.next_state = SERMOUSE_STATE_NULL;
|
||||
@@ -107,11 +107,10 @@ uint32_t sermouse_init() {
|
||||
mouse_state.report_interval_us = 0;
|
||||
mouse_state.rx_interval_us = 0;
|
||||
|
||||
// set default internal values
|
||||
// TODO: load from persistent storage (like Flash ROM)
|
||||
sermouse_set_protocol(SERMOUSE_PROTOCOL_INTELLIMOUSE);
|
||||
sermouse_set_report_rate_hz(SERMOUSE_REPORTRATE_DEFAULT);
|
||||
sermouse_set_sensitivity(0x100);
|
||||
// set internal values
|
||||
sermouse_set_protocol(protocol);
|
||||
sermouse_set_report_rate_hz(report_rate_hz);
|
||||
sermouse_set_sensitivity(sensitivity);
|
||||
|
||||
// set initialized flag
|
||||
mouse_state.initialized = 1;
|
||||
|
||||
+1
-1
@@ -111,7 +111,7 @@ struct sermouse_state_t {
|
||||
|
||||
// --------------------------
|
||||
// any core
|
||||
uint32_t sermouse_init();
|
||||
uint32_t sermouse_init(uint8_t protocol, uint8_t report_rate_hz, int16_t sensitivity);
|
||||
uint32_t sermouse_attach_uart();
|
||||
uint32_t sermouse_done();
|
||||
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "tusb.h"
|
||||
#include "mouse/8250uart.h"
|
||||
#include "mouse/sermouse.h"
|
||||
|
||||
// #include <string.h>
|
||||
|
||||
#ifdef USE_ALARM
|
||||
#include "pico_pic.h"
|
||||
#endif
|
||||
|
||||
void play_usb() {
|
||||
puts("starting core 1 USB");
|
||||
|
||||
// board_init();
|
||||
|
||||
#ifdef USE_ALARM
|
||||
// Init PIC on this core so it handles timers
|
||||
PIC_Init();
|
||||
puts("pic inited on core 1");
|
||||
#endif
|
||||
|
||||
// init host stack on configured roothub port
|
||||
tuh_init(BOARD_TUH_RHPORT);
|
||||
|
||||
for (;;) {
|
||||
// tinyusb host task
|
||||
tuh_task();
|
||||
|
||||
// mouse task
|
||||
sermouse_core1_task();
|
||||
|
||||
// uart emulation task
|
||||
uartemu_core1_task();
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -9,7 +9,7 @@ extern Settings settings;
|
||||
#include "pico_pic.h"
|
||||
#endif
|
||||
|
||||
#ifdef USB_JOYSTICK
|
||||
#ifdef USB_STACK
|
||||
#include "tusb.h"
|
||||
#endif
|
||||
|
||||
@@ -19,7 +19,7 @@ void play_mpu() {
|
||||
puts("starting core 1 MPU");
|
||||
flash_safe_execute_core_init();
|
||||
|
||||
#ifdef USB_JOYSTICK
|
||||
#ifdef USB_STACK
|
||||
// Init TinyUSB for joystick support
|
||||
tuh_init(BOARD_TUH_RHPORT);
|
||||
#endif
|
||||
@@ -33,7 +33,7 @@ void play_mpu() {
|
||||
|
||||
for (;;) {
|
||||
send_midi_byte(); // see if we need to send a byte
|
||||
#ifdef USB_JOYSTICK
|
||||
#ifdef USB_STACK
|
||||
// Service TinyUSB events
|
||||
tuh_task();
|
||||
#endif
|
||||
|
||||
+1
-8
@@ -5,14 +5,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum {
|
||||
PICO_FIRMWARE_IDLE = 0,
|
||||
PICO_FIRMWARE_WRITING = 1,
|
||||
PICO_FIRMWARE_BUSY = 2,
|
||||
PICO_FIRMWARE_DONE = 0xFE,
|
||||
PICO_FIRMWARE_ERROR = 0xFF
|
||||
} pico_firmware_status_t;
|
||||
#include "../common/picogus.h"
|
||||
|
||||
void pico_firmware_write(uint8_t data);
|
||||
void pico_firmware_start();
|
||||
|
||||
+254
-283
@@ -15,18 +15,9 @@
|
||||
#include "hardware/watchdog.h"
|
||||
#include "hardware/structs/watchdog.h"
|
||||
|
||||
enum board_type { PICO_BASED = 0, PICOGUS_2 = 1 } BOARD_TYPE;
|
||||
#include "../common/picogus.h"
|
||||
|
||||
typedef enum {
|
||||
GUS_MODE = 0,
|
||||
ADLIB_MODE = 1, // deprecated
|
||||
MPU_MODE = 2,
|
||||
TANDY_MODE = 3,
|
||||
CMS_MODE = 4,
|
||||
SB_MODE = 5,
|
||||
MOUSE_ONLY_MODE = 0x0E, // clarify later
|
||||
JOYSTICK_ONLY_MODE = 0x0f
|
||||
} card_mode_t;
|
||||
board_type_t BOARD_TYPE;
|
||||
|
||||
#ifdef PSRAM
|
||||
#include "psram_spi.h"
|
||||
@@ -49,22 +40,19 @@ uint LED_PIN;
|
||||
M62429* m62429;
|
||||
|
||||
#ifdef SOUND_SB
|
||||
#include "opl.h"
|
||||
static uint16_t basePort;
|
||||
static uint16_t sb_port_test;
|
||||
|
||||
extern void sbdsp_write(uint8_t address, uint8_t value);
|
||||
extern uint8_t sbdsp_read(uint8_t address);
|
||||
extern void sbdsp_init();
|
||||
extern void sbdsp_process();
|
||||
#endif
|
||||
#ifdef SOUND_OPL
|
||||
#include "opl.h"
|
||||
void play_adlib(void);
|
||||
extern "C" int OPL_Pico_Init(unsigned int);
|
||||
extern "C" unsigned int OPL_Pico_PortRead(opl_port_t);
|
||||
#include "cmd_buffers.h"
|
||||
cms_buffer_t opl_buffer = { {0}, 0, 0 };
|
||||
|
||||
extern void sbdsp_write(uint8_t address, uint8_t value);
|
||||
extern uint8_t sbdsp_read(uint8_t address);
|
||||
extern void sbdsp_init();
|
||||
extern void sbdsp_process();
|
||||
static uint16_t adlib_basePort;
|
||||
static bool adlib_wait;
|
||||
#endif
|
||||
|
||||
#ifdef SOUND_GUS
|
||||
@@ -72,7 +60,6 @@ static bool adlib_wait;
|
||||
|
||||
#include "isa_dma.h"
|
||||
dma_inst_t dma_config;
|
||||
static uint16_t basePort;
|
||||
static uint16_t gus_port_test;
|
||||
void play_gus(void);
|
||||
#endif
|
||||
@@ -80,13 +67,11 @@ void play_gus(void);
|
||||
|
||||
#ifdef SOUND_MPU
|
||||
#include "mpu401/export.h"
|
||||
static uint16_t basePort;
|
||||
void play_mpu(void);
|
||||
#endif
|
||||
|
||||
#ifdef SOUND_TANDY
|
||||
#include "square/square.h"
|
||||
static uint16_t basePort;
|
||||
void play_tandy(void);
|
||||
|
||||
#include "cmd_buffers.h"
|
||||
@@ -94,7 +79,6 @@ tandy_buffer_t tandy_buffer = { {0}, 0, 0 };
|
||||
#endif
|
||||
|
||||
#ifdef SOUND_CMS
|
||||
static uint16_t basePort;
|
||||
void play_cms(void);
|
||||
static uint8_t cms_detect = 0xFF;
|
||||
|
||||
@@ -103,31 +87,20 @@ cms_buffer_t cms_buffer = { {0}, 0, 0 };
|
||||
#endif
|
||||
|
||||
#ifdef USB_JOYSTICK
|
||||
static uint16_t joyPort;
|
||||
#ifdef USB_JOYSTICK_ONLY
|
||||
void play_usb(void);
|
||||
#endif
|
||||
#include "joy_hid/joy.h"
|
||||
extern "C" joystate_struct_t joystate_struct;
|
||||
uint8_t joystate_bin;
|
||||
#include "hardware/pwm.h"
|
||||
#endif
|
||||
|
||||
#ifdef USB_MOUSE
|
||||
static uint16_t mousePort = 0x2F8; // emulate at COM2
|
||||
static uint8_t mouseSensitivity_low;
|
||||
#include "mouse/8250uart.h"
|
||||
#include "mouse/sermouse.h"
|
||||
extern uart_state_t uart_state;
|
||||
void play_usb(void); // FIXME!!!!
|
||||
#endif
|
||||
#ifdef USB_ONLY
|
||||
void play_usb(void);
|
||||
#endif
|
||||
|
||||
// PicoGUS control and data ports
|
||||
// 1D0 chosen as the base port as nothing is listed in Ralf Brown's Port List (http://www.cs.cmu.edu/~ralf/files.html)
|
||||
#define CONTROL_PORT 0x1D0
|
||||
#define DATA_PORT_LOW 0x1D1
|
||||
#define DATA_PORT_HIGH 0x1D2
|
||||
#define PICOGUS_PROTOCOL_VER 2
|
||||
static bool control_active = false;
|
||||
static uint8_t sel_reg = 0;
|
||||
static uint16_t cur_data = 0;
|
||||
@@ -136,63 +109,64 @@ static bool queueSaveSettings = false;
|
||||
static bool queueReboot = false;
|
||||
|
||||
Settings settings;
|
||||
void processSettings(void);
|
||||
|
||||
#define IOW_PIO_SM 0
|
||||
#define IOR_PIO_SM 1
|
||||
|
||||
const char* firmware_string = PICO_PROGRAM_NAME " v" PICO_PROGRAM_VERSION_STRING;
|
||||
|
||||
uint16_t basePort_tmp;
|
||||
uint16_t multifw_tmp;
|
||||
static uint8_t basePort_low;
|
||||
static uint8_t mouseSensitivity_low;
|
||||
|
||||
__force_inline void select_picogus(uint8_t value) {
|
||||
// printf("select picogus %x\n", value);
|
||||
sel_reg = value;
|
||||
switch (sel_reg) {
|
||||
case 0x00: // Magic string
|
||||
case 0x01: // Protocol version
|
||||
case MODE_MAGIC: // Magic string
|
||||
case MODE_PROTOCOL: // Protocol version
|
||||
break;
|
||||
case 0x02: // Firmware string
|
||||
case MODE_FWSTRING: // Firmware string
|
||||
cur_read = 0;
|
||||
break;
|
||||
case 0x03: // Mode (GUS, OPL, MPU, etc...)
|
||||
case MODE_MODE: // Mode (GUS, OPL, MPU, etc...)
|
||||
break;
|
||||
case 0x04: // Base port
|
||||
case 0x05: // Adlib Base port
|
||||
basePort_tmp = 0;
|
||||
case MODE_GUSPORT: // GUS Base port
|
||||
case MODE_OPLPORT: // Adlib Base port
|
||||
case MODE_SBPORT: // SB Base port
|
||||
case MODE_MPUPORT: // MPU Base port
|
||||
case MODE_TANDYPORT: // Tandy Base port
|
||||
case MODE_CMSPORT: // CMS Base port
|
||||
basePort_low = 0;
|
||||
break;
|
||||
case 0x0f: // enable joystick
|
||||
case MODE_JOYEN: // enable joystick
|
||||
break;
|
||||
#ifdef SOUND_GUS
|
||||
case 0x10: // Audio buffer size
|
||||
case 0x11: // DMA interval
|
||||
case 0x12: // Force 44k
|
||||
case MODE_GUSBUF: // Audio buffer size
|
||||
case MODE_GUSDMA: // DMA interval
|
||||
case MODE_GUS44K: // Force 44k
|
||||
break;
|
||||
#endif
|
||||
case 0x20: // Wavetable mixer volume
|
||||
case MODE_WTVOL: // Wavetable mixer volume
|
||||
break;
|
||||
#ifdef SOUND_MPU
|
||||
case 0x21: // MPU init
|
||||
case MODE_MPUDELAY: // MPU sysex delay
|
||||
case MODE_MPUFAKE: // MPU fake all notes off
|
||||
break;
|
||||
#endif
|
||||
#ifdef SOUND_SB
|
||||
case 0x30: // Adlib speed sensitive fix
|
||||
case MODE_OPLWAIT: // Adlib speed sensitive fix
|
||||
break;
|
||||
#ifdef USB_MOUSE
|
||||
case 0x40:
|
||||
case 0x41:
|
||||
case 0x42:
|
||||
case 0x43:
|
||||
case MODE_MOUSEPORT:
|
||||
basePort_low = 0;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
case 0xE0: // Select firmware boot mode register
|
||||
case 0xE1: // Select save settings register
|
||||
case 0xE2: // Select reboot register
|
||||
case MODE_MOUSEPROTO:
|
||||
case MODE_MOUSERATE:
|
||||
case MODE_MOUSESEN:
|
||||
break;
|
||||
case 0xF0: // Hardware version
|
||||
case MODE_BOOTMODE: // Select firmware boot mode register
|
||||
case MODE_SAVE: // Select save settings register
|
||||
case MODE_REBOOT: // Select reboot register
|
||||
case MODE_DEFAULTS: // Select reset to defaults register
|
||||
break;
|
||||
case 0xFF: // Firmware write mode
|
||||
case MODE_HWTYPE: // Hardware version
|
||||
break;
|
||||
case MODE_FLASH: // Firmware write mode
|
||||
pico_firmware_start();
|
||||
break;
|
||||
default:
|
||||
@@ -203,119 +177,129 @@ __force_inline void select_picogus(uint8_t value) {
|
||||
|
||||
__force_inline void write_picogus_low(uint8_t value) {
|
||||
switch (sel_reg) {
|
||||
case 0x04: // Base port
|
||||
case 0x05: // Adlib Base port
|
||||
basePort_tmp = value;
|
||||
case MODE_GUSPORT: // GUS Base port
|
||||
case MODE_OPLPORT: // Adlib Base port
|
||||
case MODE_SBPORT: // SB Base port
|
||||
case MODE_MPUPORT: // MPU Base port
|
||||
case MODE_TANDYPORT: // Tandy Base port
|
||||
case MODE_CMSPORT: // CMS Base port
|
||||
case MODE_MOUSEPORT: // USB Mouse port (0 - disabled)
|
||||
basePort_low = value;
|
||||
break;
|
||||
#ifdef USB_MOUSE
|
||||
case 0x30: // USB Mouse port (0 - disabled)
|
||||
mousePort = value;
|
||||
break;
|
||||
case 0x33: // USB Mouse Sensitivity (8.8 fixedpoint)
|
||||
case MODE_MOUSESEN: // USB Mouse Sensitivity (8.8 fixedpoint)
|
||||
mouseSensitivity_low = value;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
__force_inline void write_picogus_high(uint8_t value) {
|
||||
switch (sel_reg) {
|
||||
case 0x04: // Base port
|
||||
#if defined(SOUND_GUS) || defined(SOUND_SB) || defined(SOUND_MPU) || defined(SOUND_TANDY) || defined(SOUND_CMS)
|
||||
basePort = (value << 8) | basePort_tmp;
|
||||
#endif
|
||||
case MODE_GUSPORT: // GUS Base port
|
||||
settings.GUS.basePort = (value && basePort_low) ? ((value << 8) | (basePort_low & 0xFF)) : 0xFFFF;
|
||||
#ifdef SOUND_GUS
|
||||
settings.GUS.basePort = basePort;
|
||||
gus_port_test = basePort >> 4 | 0x10;
|
||||
// GUS_SetPort(basePort);
|
||||
gus_port_test = settings.GUS.basePort >> 4 | 0x10;
|
||||
#endif
|
||||
break;
|
||||
case MODE_OPLPORT: // Adlib Base port
|
||||
settings.SB.oplBasePort = (value && basePort_low) ? ((value << 8) | (basePort_low & 0xFF)) : 0xFFFF;
|
||||
break;
|
||||
case MODE_SBPORT: // SB Base port
|
||||
settings.SB.basePort = (value && basePort_low) ? ((value << 8) | (basePort_low & 0xFF)) : 0xFFFF;
|
||||
#ifdef SOUND_SB
|
||||
settings.SB.basePort = basePort;
|
||||
sb_port_test = basePort >> 4;
|
||||
#endif
|
||||
#ifdef SOUND_MPU
|
||||
settings.MPU.basePort = basePort;
|
||||
#endif
|
||||
#ifdef SOUND_TANDY
|
||||
settings.Tandy.basePort = basePort;
|
||||
#endif
|
||||
#ifdef SOUND_CMS
|
||||
settings.CMS.basePort = basePort;
|
||||
sb_port_test = settings.SB.basePort >> 4;
|
||||
#endif
|
||||
break;
|
||||
case 0x05: // Adlib Base port
|
||||
#ifdef SOUND_SB
|
||||
adlib_basePort = (value << 8) | basePort_tmp;
|
||||
settings.SB.oplBasePort = adlib_basePort;
|
||||
#endif
|
||||
case MODE_MPUPORT: // MPU Base port
|
||||
settings.MPU.basePort = (value && basePort_low) ? ((value << 8) | (basePort_low & 0xFF)) : 0xFFFF;
|
||||
break;
|
||||
case 0x0f: // enable joystick
|
||||
#ifdef USB_JOYSTICK
|
||||
joyPort = value ? 0x201u : 0xffff;
|
||||
settings.Joy.basePort = joyPort;
|
||||
#endif
|
||||
case MODE_TANDYPORT: // Tandy Base port
|
||||
settings.Tandy.basePort = (value && basePort_low) ? ((value << 8) | (basePort_low & 0xFF)) : 0xFFFF;
|
||||
break;
|
||||
#ifdef SOUND_GUS
|
||||
case 0x10: // Audio buffer size
|
||||
case MODE_CMSPORT: // CMS Base port
|
||||
settings.CMS.basePort = (value && basePort_low) ? ((value << 8) | (basePort_low & 0xFF)) : 0xFFFF;
|
||||
break;
|
||||
case MODE_JOYEN: // enable joystick
|
||||
settings.Joy.basePort = value ? 0x201u : 0xffff;
|
||||
break;
|
||||
case MODE_GUSBUF: // GUS audio buffer size
|
||||
// Value is sent by pgusinit as the size - 1, so we need to add 1 back to it
|
||||
GUS_SetAudioBuffer(value + 1);
|
||||
settings.GUS.audioBuffer = value + 1;
|
||||
break;
|
||||
case 0x11: // DMA interval
|
||||
GUS_SetDMAInterval(value);
|
||||
settings.GUS.dmaInterval = value;
|
||||
break;
|
||||
case 0x12: // Force 44k output
|
||||
GUS_SetFixed44k(value);
|
||||
settings.GUS.force44k = value;
|
||||
break;
|
||||
#ifdef SOUND_GUS
|
||||
GUS_SetAudioBuffer(settings.GUS.audioBuffer);
|
||||
#endif
|
||||
case 0x20: // Wavetable mixer volume
|
||||
break;
|
||||
case MODE_GUSDMA: // GUS DMA interval
|
||||
settings.GUS.dmaInterval = value;
|
||||
#ifdef SOUND_GUS
|
||||
GUS_SetDMAInterval(settings.GUS.dmaInterval);
|
||||
#endif
|
||||
break;
|
||||
case MODE_GUS44K: // Force 44k output
|
||||
settings.GUS.force44k = value;
|
||||
#ifdef SOUND_GUS
|
||||
GUS_SetFixed44k(settings.GUS.force44k);
|
||||
#endif
|
||||
break;
|
||||
case MODE_WTVOL: // Wavetable mixer volume
|
||||
settings.Global.waveTableVolume = value;
|
||||
if (BOARD_TYPE == PICOGUS_2) {
|
||||
m62429->setVolume(M62429_BOTH, value);
|
||||
settings.Global.waveTableVolume = value;
|
||||
m62429->setVolume(M62429_BOTH, settings.Global.waveTableVolume);
|
||||
}
|
||||
break;
|
||||
case MODE_MPUDELAY: // MPU SYSEX delay
|
||||
settings.MPU.delaySysex = value;
|
||||
#ifdef SOUND_MPU
|
||||
case 0x21: // MIDI emulation flags
|
||||
MPU401_Init(value & 0x1 /* delaysysex */, value & 0x2 /* fakeallnotesoff */);
|
||||
settings.MPU.delaySysex = value & 0x1;
|
||||
settings.MPU.fakeAllNotesOff = value & 0x2;
|
||||
break;
|
||||
MPU401_Init(settings.MPU.delaySysex, settings.MPU.fakeAllNotesOff);
|
||||
#endif
|
||||
#ifdef SOUND_SB
|
||||
case 0x30: // Adlib speed sensitive fix
|
||||
adlib_wait = value;
|
||||
break;
|
||||
case MODE_MPUFAKE: // MPU fake all notes off
|
||||
settings.MPU.fakeAllNotesOff = value;
|
||||
#ifdef SOUND_MPU
|
||||
MPU401_Init(settings.MPU.delaySysex, settings.MPU.fakeAllNotesOff);
|
||||
#endif
|
||||
break;
|
||||
case MODE_OPLWAIT: // Adlib speed sensitive fix
|
||||
settings.SB.oplSpeedSensitive = value;
|
||||
break;
|
||||
case MODE_MOUSEPORT: // USB Mouse port (0 - disabled)
|
||||
settings.Mouse.basePort = (value && basePort_low) ? ((value << 8) | (basePort_low & 0xFF)) : 0xFFFF;
|
||||
break;
|
||||
case MODE_MOUSEPROTO: // USB Mouse protocol
|
||||
settings.Mouse.protocol = value;
|
||||
#ifdef USB_MOUSE
|
||||
case 0x40: // USB Mouse port (0 - disabled)
|
||||
uart_state.iobase = value ? ((value << 8) | (mousePort & 0xFF)) : 0xFFFF;
|
||||
break;
|
||||
case 0x41: // USB Mouse protocol
|
||||
sermouse_set_protocol(value);
|
||||
break;
|
||||
case 0x42: // USB Mouse Report Rate
|
||||
sermouse_set_report_rate_hz(value);
|
||||
break;
|
||||
case 0x43: // USB Mouse Sensitivity (8.8 fixedpoint)
|
||||
sermouse_set_sensitivity((value << 8) | (mouseSensitivity_low & 0xFF));
|
||||
break;
|
||||
sermouse_set_protocol(settings.Mouse.protocol);
|
||||
#endif
|
||||
break;
|
||||
case MODE_MOUSERATE: // USB Mouse Report Rate
|
||||
settings.Mouse.reportRate = value;
|
||||
#ifdef USB_MOUSE
|
||||
sermouse_set_report_rate_hz(settings.Mouse.reportRate);
|
||||
#endif
|
||||
break;
|
||||
case MODE_MOUSESEN: // USB Mouse Sensitivity (8.8 fixedpoint)
|
||||
settings.Mouse.sensitivity = (value << 8) | (mouseSensitivity_low & 0xFF);
|
||||
#ifdef USB_MOUSE
|
||||
sermouse_set_sensitivity(settings.Mouse.sensitivity);
|
||||
#endif
|
||||
break;
|
||||
// For multifw
|
||||
case 0xE0:
|
||||
// set firmware num, perm flag and reboot
|
||||
case MODE_BOOTMODE:
|
||||
settings.startupMode = value;
|
||||
printf("requesting startup mode: %u\n", value);
|
||||
break;
|
||||
case 0xE1:
|
||||
case MODE_SAVE:
|
||||
queueSaveSettings = true;
|
||||
break;
|
||||
case 0xE2:
|
||||
case MODE_REBOOT:
|
||||
watchdog_hw->scratch[3] = settings.startupMode;
|
||||
printf("rebooting into mode: %u\n", settings.startupMode);
|
||||
watchdog_reboot(0, 0, 0);
|
||||
case 0xff: // Firmware write
|
||||
break;
|
||||
case MODE_DEFAULTS:
|
||||
getDefaultSettings(&settings);
|
||||
processSettings();
|
||||
break;
|
||||
case MODE_FLASH: // Firmware write
|
||||
pico_firmware_write(value);
|
||||
break;
|
||||
}
|
||||
@@ -323,25 +307,22 @@ __force_inline void write_picogus_high(uint8_t value) {
|
||||
|
||||
__force_inline uint8_t read_picogus_low(void) {
|
||||
switch (sel_reg) {
|
||||
case 0x04: // Base port
|
||||
#if defined(SOUND_GUS) || defined(SOUND_SB) || defined(SOUND_MPU) || defined(SOUND_TANDY) || defined(SOUND_CMS)
|
||||
return basePort & 0xff;
|
||||
#else
|
||||
return 0xff;
|
||||
#endif
|
||||
#ifdef USB_MOUSE
|
||||
case 0x30: // USB Mouse port (0 - disabled)
|
||||
return uart_state.iobase == 0xFFFF ? 0 : (uart_state.iobase & 0xFF);
|
||||
case 0x33: // USB Mouse Sensitivity (8.8 fixedpoint)
|
||||
return (sermouse_get_sensitivity() & 0xFF);
|
||||
#endif
|
||||
break;
|
||||
case 0x05: // Adlib Base port
|
||||
#if defined(SOUND_SB)
|
||||
return adlib_basePort & 0xff;
|
||||
#else
|
||||
return 0xff;
|
||||
#endif
|
||||
case MODE_GUSPORT: // GUS Base port
|
||||
return settings.GUS.basePort == 0xFFFF ? 0 : (settings.Mouse.basePort & 0xFF);
|
||||
case MODE_OPLPORT: // Adlib Base port
|
||||
return settings.SB.oplBasePort == 0xFFFF ? 0 : (settings.Mouse.basePort & 0xFF);
|
||||
case MODE_SBPORT: // SB Base port
|
||||
return settings.SB.basePort == 0xFFFF ? 0 : (settings.Mouse.basePort & 0xFF);
|
||||
case MODE_MPUPORT: // MPU Base port
|
||||
return settings.MPU.basePort == 0xFFFF ? 0 : (settings.Mouse.basePort & 0xFF);
|
||||
case MODE_TANDYPORT: // Tandy Base port
|
||||
return settings.Tandy.basePort == 0xFFFF ? 0 : (settings.Mouse.basePort & 0xFF);
|
||||
case MODE_CMSPORT: // CMS Base port
|
||||
return settings.CMS.basePort == 0xFFFF ? 0 : (settings.Mouse.basePort & 0xFF);
|
||||
case MODE_MOUSEPORT: // USB Mouse port (0 - disabled)
|
||||
return settings.Mouse.basePort == 0xFFFF ? 0 : (settings.Mouse.basePort & 0xFF);
|
||||
case MODE_MOUSESEN: // USB Mouse Sensitivity (8.8 fixedpoint)
|
||||
return settings.Mouse.sensitivity & 0xFF;
|
||||
default:
|
||||
return 0x0;
|
||||
}
|
||||
@@ -350,20 +331,17 @@ __force_inline uint8_t read_picogus_low(void) {
|
||||
__force_inline uint8_t read_picogus_high(void) {
|
||||
uint8_t ret;
|
||||
switch (sel_reg) {
|
||||
case 0x00: // PicoGUS magic string
|
||||
case MODE_MAGIC: // PicoGUS magic string
|
||||
return 0xdd;
|
||||
break;
|
||||
case 0x01: // PicoGUS protocol version
|
||||
case MODE_PROTOCOL: // PicoGUS protocol version
|
||||
return PICOGUS_PROTOCOL_VER;
|
||||
break;
|
||||
case 0x02: // Firmware string
|
||||
case MODE_FWSTRING: // Firmware string
|
||||
ret = firmware_string[cur_read++];
|
||||
if (ret == 0) { // Null terminated
|
||||
cur_read = 0;
|
||||
}
|
||||
return ret;
|
||||
break;
|
||||
case 0x03: // Mode (GUS, OPL, MPU, etc...)
|
||||
case MODE_MODE: // Mode (GUS, OPL, MPU, etc...)
|
||||
#if defined(SOUND_GUS)
|
||||
return GUS_MODE;
|
||||
#elif defined(SOUND_MPU)
|
||||
@@ -374,88 +352,78 @@ __force_inline uint8_t read_picogus_high(void) {
|
||||
return CMS_MODE;
|
||||
#elif defined(SOUND_SB)
|
||||
return SB_MODE;
|
||||
#elif defined(USB_JOYSTICK_ONLY)
|
||||
return JOYSTICK_ONLY_MODE;
|
||||
#elif defined(USB_MOUSE_ONLY)
|
||||
return MOUSE_ONLY_MODE;
|
||||
#elif defined(SOUND_OPL)
|
||||
return ADLIB_MODE;
|
||||
#elif defined(USB_ONLY)
|
||||
return USB_MODE;
|
||||
#else
|
||||
return 0xff;
|
||||
return INVALID_MODE;
|
||||
#endif
|
||||
break;
|
||||
case 0x04: // Base port
|
||||
#if defined(SOUND_GUS) || defined(SOUND_SB) || defined(SOUND_MPU) || defined(SOUND_TANDY) || defined(SOUND_CMS)
|
||||
return basePort >> 8;
|
||||
#else
|
||||
return 0xff;
|
||||
#endif
|
||||
break;
|
||||
case 0x05: // Adlib Base port
|
||||
#if defined(SOUND_SB)
|
||||
return adlib_basePort >> 8;
|
||||
#else
|
||||
return 0xff;
|
||||
#endif
|
||||
break;
|
||||
case 0x0f: // enable joystick
|
||||
#ifdef USB_JOYSTICK
|
||||
return joyPort == 0x201u;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
case 0x20: // Wavetable mixer volume
|
||||
if (BOARD_TYPE == PICOGUS_2) {
|
||||
return m62429->getVolume(0);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
#ifdef USB_MOUSE
|
||||
case 0x40: // USB Mouse port (0 - disabled)
|
||||
return uart_state.iobase == 0xFFFF ? 0 : (uart_state.iobase >> 8);
|
||||
break;
|
||||
case 0x41: // USB Mouse protocol
|
||||
return sermouse_get_protocol();
|
||||
break;
|
||||
case 0x42: // USB Mouse Report Rate
|
||||
return sermouse_get_report_rate_hz();
|
||||
break;
|
||||
case 0x43: // USB Mouse Sensitivity (8.8 fixedpoint)
|
||||
return (sermouse_get_sensitivity() >> 8);
|
||||
break;
|
||||
#endif
|
||||
case 0xF0: // Hardware version
|
||||
case MODE_GUSPORT: // GUS Base port
|
||||
return settings.GUS.basePort >> 8;
|
||||
case MODE_OPLPORT: // Adlib Base port
|
||||
return settings.SB.oplBasePort >> 8;
|
||||
case MODE_SBPORT: // SB Base port
|
||||
return settings.SB.basePort >> 8;
|
||||
case MODE_MPUPORT: // MPU Base port
|
||||
return settings.MPU.basePort >> 8;
|
||||
case MODE_TANDYPORT: // Tandy Base port
|
||||
return settings.Tandy.basePort >> 8;
|
||||
case MODE_CMSPORT: // CMS Base port
|
||||
return settings.CMS.basePort >> 8;
|
||||
case MODE_JOYEN: // enable joystick
|
||||
return settings.Joy.basePort == 0x201u;
|
||||
case MODE_GUSBUF: // GUS audio buffer size
|
||||
return settings.GUS.audioBuffer - 1;
|
||||
case MODE_GUSDMA: // GUS DMA interval
|
||||
return settings.GUS.dmaInterval;
|
||||
case MODE_GUS44K: // Force 44k output
|
||||
return settings.GUS.force44k;
|
||||
case MODE_WTVOL: // Wavetable mixer volume
|
||||
return (BOARD_TYPE == PICOGUS_2) ? m62429->getVolume(0) : 0;
|
||||
case MODE_MPUDELAY: // SYSEX delay
|
||||
return settings.MPU.delaySysex;
|
||||
case MODE_MPUFAKE: // MPU fake all notes off
|
||||
return settings.MPU.fakeAllNotesOff;
|
||||
case MODE_OPLWAIT: // Adlib speed sensitive fix
|
||||
return settings.SB.oplSpeedSensitive;
|
||||
case MODE_MOUSEPORT: // USB Mouse port (0 - disabled)
|
||||
return settings.Mouse.basePort == 0xFFFF ? 0 : (settings.Mouse.basePort >> 8);
|
||||
case MODE_MOUSEPROTO: // USB Mouse protocol
|
||||
return settings.Mouse.protocol;
|
||||
case MODE_MOUSERATE: // USB Mouse Report Rate
|
||||
return settings.Mouse.reportRate;
|
||||
case MODE_MOUSESEN: // USB Mouse Sensitivity (8.8 fixedpoint)
|
||||
return settings.Mouse.sensitivity >> 8;
|
||||
case MODE_HWTYPE: // Hardware version
|
||||
return BOARD_TYPE;
|
||||
case 0xff:
|
||||
case MODE_FLASH:
|
||||
// Get status of firmware write
|
||||
return pico_firmware_getStatus();
|
||||
break;
|
||||
default:
|
||||
return 0xff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void processSettings(void) {
|
||||
#ifdef SOUND_SB
|
||||
basePort = settings.SB.basePort;
|
||||
sb_port_test = basePort >> 4;
|
||||
adlib_basePort = settings.SB.oplBasePort;
|
||||
adlib_wait = settings.SB.oplSpeedSensitive;
|
||||
sb_port_test = settings.SB.basePort >> 4;
|
||||
#endif
|
||||
#ifdef SOUND_GUS
|
||||
basePort = settings.GUS.basePort;
|
||||
gus_port_test = basePort >> 4 | 0x10;
|
||||
gus_port_test = settings.GUS.basePort >> 4 | 0x10;
|
||||
GUS_SetFixed44k(settings.GUS.force44k);
|
||||
GUS_SetAudioBuffer(settings.GUS.audioBuffer);
|
||||
GUS_SetDMAInterval(settings.GUS.dmaInterval);
|
||||
#endif
|
||||
#ifdef SOUND_MPU
|
||||
basePort = settings.MPU.basePort;
|
||||
#endif
|
||||
#ifdef SOUND_CMS
|
||||
basePort = settings.CMS.basePort;
|
||||
#endif
|
||||
#ifdef SOUND_TANDY
|
||||
basePort = settings.Tandy.basePort;
|
||||
#ifdef USB_MOUSE
|
||||
sermouse_set_protocol(settings.Mouse.protocol);
|
||||
sermouse_set_report_rate_hz(settings.Mouse.reportRate);
|
||||
sermouse_set_sensitivity(settings.Mouse.sensitivity);
|
||||
#endif
|
||||
if (BOARD_TYPE == PICOGUS_2) {
|
||||
m62429->setVolume(M62429_BOTH, settings.Global.waveTableVolume);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -471,7 +439,7 @@ __force_inline void handle_iow(void) {
|
||||
// printf("IOW: %x %x\n", port, iow_read & 0xFF);
|
||||
#ifdef SOUND_GUS
|
||||
if ((port >> 4 | 0x10) == gus_port_test) {
|
||||
port -= basePort;
|
||||
port -= settings.GUS.basePort;
|
||||
switch (port) {
|
||||
case 0x8:
|
||||
case 0xb:
|
||||
@@ -498,7 +466,7 @@ __force_inline void handle_iow(void) {
|
||||
#endif // SOUND_GUS
|
||||
#ifdef SOUND_SB
|
||||
if ((port >> 4) == sb_port_test) {
|
||||
switch (port - basePort) {
|
||||
switch (port - settings.SB.basePort) {
|
||||
// OPL ports
|
||||
case 0x8:
|
||||
// Fast write
|
||||
@@ -525,7 +493,10 @@ __force_inline void handle_iow(void) {
|
||||
sbdsp_process();
|
||||
break;
|
||||
}
|
||||
} else if (port == adlib_basePort) {
|
||||
} else // if follows down below
|
||||
#endif // SOUND_SB
|
||||
#if defined(SOUND_OPL)
|
||||
if (port == settings.SB.oplBasePort) {
|
||||
// Fast write
|
||||
pio_sm_put(pio0, IOW_PIO_SM, IO_END);
|
||||
opl_buffer.cmds[opl_buffer.head++] = {
|
||||
@@ -534,9 +505,9 @@ __force_inline void handle_iow(void) {
|
||||
};
|
||||
// Fast write - return early as we've already written 0x0u to the PIO
|
||||
return;
|
||||
} else if (port == adlib_basePort + 1) {
|
||||
} else if (port == settings.SB.oplBasePort + 1) {
|
||||
pio_sm_put(pio0, IOW_PIO_SM, IO_WAIT);
|
||||
if (adlib_wait) {
|
||||
if (settings.SB.oplSpeedSensitive) {
|
||||
busy_wait_us(1); // busy wait for speed sensitive games
|
||||
}
|
||||
opl_buffer.cmds[opl_buffer.head++] = {
|
||||
@@ -544,9 +515,9 @@ __force_inline void handle_iow(void) {
|
||||
(uint8_t)(iow_read & 0xFF)
|
||||
};
|
||||
} else // if follows down below
|
||||
#endif // SOUND_SB
|
||||
#endif // SOUND_OPL
|
||||
#ifdef SOUND_MPU
|
||||
switch (port - basePort) {
|
||||
switch (port - settings.MPU.basePort) {
|
||||
case 0:
|
||||
pio_sm_put(pio0, IOW_PIO_SM, IO_WAIT);
|
||||
// printf("MPU IOW: port: %x value: %x\n", port, iow_read & 0xFF);
|
||||
@@ -562,14 +533,14 @@ __force_inline void handle_iow(void) {
|
||||
}
|
||||
#endif // SOUND_MPU
|
||||
#ifdef SOUND_TANDY
|
||||
if (port == basePort) {
|
||||
if (port == settings.Tandy.basePort) {
|
||||
pio_sm_put(pio0, IOW_PIO_SM, IO_END);
|
||||
tandy_buffer.cmds[tandy_buffer.head++] = iow_read & 0xFF;
|
||||
return;
|
||||
} else // if follows down below
|
||||
#endif // SOUND_TANDY
|
||||
#ifdef SOUND_CMS
|
||||
switch (port - basePort) {
|
||||
switch (port - settings.CMS.basePort) {
|
||||
// SAA data/address ports
|
||||
case 0x0:
|
||||
case 0x1:
|
||||
@@ -592,7 +563,7 @@ __force_inline void handle_iow(void) {
|
||||
}
|
||||
#endif // SOUND_CMS
|
||||
#ifdef USB_JOYSTICK
|
||||
if (port == joyPort) {
|
||||
if (port == settings.Joy.basePort) {
|
||||
pio_sm_put(pio0, IOW_PIO_SM, IO_END);
|
||||
// Set times in # of cycles (affected by clkdiv) for each PWM slice to count up and wrap back to 0
|
||||
// TODO better calibrate this
|
||||
@@ -618,7 +589,7 @@ __force_inline void handle_iow(void) {
|
||||
} else // if follows down below
|
||||
#endif // USB_JOYSTICK
|
||||
#ifdef USB_MOUSE
|
||||
if ((port & ~7) == uart_state.iobase) {
|
||||
if ((port & ~7) == settings.Mouse.basePort) {
|
||||
pio_sm_put(pio0, IOW_PIO_SM, IO_WAIT); // leave some time for UART logic emualtion
|
||||
uartemu_write(port & 7, iow_read & 0xFF);
|
||||
} else // if follows down below
|
||||
@@ -662,16 +633,17 @@ __force_inline void handle_ior(void) {
|
||||
if ((port >> 4 | 0x10) == gus_port_test) {
|
||||
// Tell PIO to wait for data
|
||||
pio_sm_put(pio0, IOR_PIO_SM, IO_WAIT);
|
||||
uint32_t value = read_gus(port - basePort) & 0xff;
|
||||
uint32_t value = read_gus(port - settings.GUS.basePort) & 0xff;
|
||||
// OR with 0x0000ff00 is required to set pindirs in the PIO
|
||||
pio_sm_put(pio0, IOR_PIO_SM, IOR_SET_VALUE | value);
|
||||
// printf("GUS IOR: port: %x value: %x\n", port, value);
|
||||
// gpio_xor_mask(LED_PIN);
|
||||
} else // if follows down below
|
||||
#elif defined(SOUND_SB)
|
||||
#endif
|
||||
#if defined(SOUND_SB)
|
||||
if ((port >> 4) == sb_port_test) {
|
||||
pio_sm_put(pio0, IOR_PIO_SM, IO_WAIT);
|
||||
if (port - basePort == 0x8) {
|
||||
if (port - settings.SB.basePort == 0x8) {
|
||||
// wait for OPL buffer to process
|
||||
while (opl_buffer.tail != opl_buffer.head) {
|
||||
tight_loop_contents();
|
||||
@@ -682,7 +654,10 @@ __force_inline void handle_ior(void) {
|
||||
pio_sm_put(pio0, IOR_PIO_SM, IOR_SET_VALUE | sbdsp_read(port & 0xF));
|
||||
sbdsp_process();
|
||||
}
|
||||
} else if (port == adlib_basePort) {
|
||||
} else // if follows down below
|
||||
#endif
|
||||
#if defined(SOUND_OPL)
|
||||
if (port == settings.SB.oplBasePort) {
|
||||
// Tell PIO to wait for data
|
||||
pio_sm_put(pio0, IOR_PIO_SM, IO_WAIT);
|
||||
// wait for OPL buffer to process
|
||||
@@ -691,15 +666,16 @@ __force_inline void handle_ior(void) {
|
||||
}
|
||||
pio_sm_put(pio0, IOR_PIO_SM, IOR_SET_VALUE | OPL_Pico_PortRead(OPL_REGISTER_PORT));
|
||||
} else // if follows down below
|
||||
#elif defined(SOUND_MPU)
|
||||
if (port == basePort) {
|
||||
#endif
|
||||
#if defined(SOUND_MPU)
|
||||
if (port == settings.MPU.basePort) {
|
||||
// Tell PIO to wait for data
|
||||
pio_sm_put(pio0, IOR_PIO_SM, IO_WAIT);
|
||||
uint32_t value = MPU401_ReadData();
|
||||
// printf("MPU IOR: port: %x value: %x\n", port, value);
|
||||
// OR with 0x0000ff00 is required to set pindirs in the PIO
|
||||
pio_sm_put(pio0, IOR_PIO_SM, IOR_SET_VALUE | value);
|
||||
} else if (port == basePort + 1) {
|
||||
} else if (port == settings.MPU.basePort + 1) {
|
||||
// Tell PIO to wait for data
|
||||
pio_sm_put(pio0, IOR_PIO_SM, IO_WAIT);
|
||||
uint32_t value = MPU401_ReadStatus();
|
||||
@@ -707,8 +683,9 @@ __force_inline void handle_ior(void) {
|
||||
// OR with 0x0000ff00 is required to set pindirs in the PIO
|
||||
pio_sm_put(pio0, IOR_PIO_SM, IOR_SET_VALUE | value);
|
||||
} else // if follows down below
|
||||
#elif defined(SOUND_CMS)
|
||||
switch (port - basePort) {
|
||||
#endif
|
||||
#if defined(SOUND_CMS)
|
||||
switch (port - settings.CMS.basePort) {
|
||||
// CMS autodetect ports
|
||||
case 0x4:
|
||||
pio_sm_put(pio0, IOR_PIO_SM, IO_WAIT);
|
||||
@@ -722,7 +699,7 @@ __force_inline void handle_ior(void) {
|
||||
}
|
||||
#endif // SOUND_CMS
|
||||
#ifdef USB_JOYSTICK
|
||||
if (port == joyPort) {
|
||||
if (port == settings.Joy.basePort) {
|
||||
pio_sm_put(pio0, IOR_PIO_SM, IO_WAIT);
|
||||
uint8_t value =
|
||||
// Proportional bits: 1 if counter is still counting, 0 otherwise
|
||||
@@ -735,7 +712,7 @@ __force_inline void handle_ior(void) {
|
||||
} else // if follows down below
|
||||
#endif // USB_JOYSTICK
|
||||
#ifdef USB_MOUSE
|
||||
if ((port & ~7) == uart_state.iobase) {
|
||||
if ((port & ~7) == settings.Mouse.basePort) {
|
||||
pio_sm_put(pio0, IOR_PIO_SM, IO_WAIT);
|
||||
uint8_t value = uartemu_read(port & 7);
|
||||
pio_sm_put(pio0, IOR_PIO_SM, IOR_SET_VALUE | value);
|
||||
@@ -807,7 +784,6 @@ __force_inline bool ior_has_data() {
|
||||
#include "hardware/structs/xip_ctrl.h"
|
||||
int main()
|
||||
{
|
||||
hw_clear_bits(&xip_ctrl_hw->ctrl, XIP_CTRL_EN_BITS);
|
||||
#ifdef ASYNC_UART
|
||||
stdio_async_uart_init_full(UART_ID, BAUD_RATE, UART_TX_PIN, UART_RX_PIN);
|
||||
#else
|
||||
@@ -825,7 +801,7 @@ int main()
|
||||
|
||||
// Load settings from flash
|
||||
loadSettings(&settings);
|
||||
processSettings();
|
||||
hw_clear_bits(&xip_ctrl_hw->ctrl, XIP_CTRL_EN_BITS);
|
||||
|
||||
// Determine board type. GPIO 29 is grounded on PicoGUS v2.0, and on a Pico, it's VSYS/3 (~1.666V)
|
||||
// GPIO 25 must be high to read GPIO 29 on the Pico W
|
||||
@@ -895,8 +871,8 @@ int main()
|
||||
m62429->begin(24, 25, pio1, -1);
|
||||
#else
|
||||
m62429->begin(24, 25);
|
||||
m62429->setVolume(M62429_BOTH, settings.Global.waveTableVolume);
|
||||
#endif // SOUND_MPU
|
||||
// Initial volume is set in processSettings()
|
||||
#endif // M62429_PIO
|
||||
}
|
||||
|
||||
gpio_init(IRQ_PIN);
|
||||
@@ -954,17 +930,16 @@ int main()
|
||||
#ifdef SOUND_SB
|
||||
puts("Initializing SoundBlaster DSP");
|
||||
sbdsp_init();
|
||||
puts("Creating OPL");
|
||||
OPL_Pico_Init(basePort);
|
||||
multicore_launch_core1(&play_adlib);
|
||||
#endif // SOUND_SB
|
||||
#ifdef SOUND_OPL
|
||||
puts("Creating OPL");
|
||||
OPL_Pico_Init(0);
|
||||
multicore_launch_core1(&play_adlib);
|
||||
#endif
|
||||
|
||||
#ifdef SOUND_GUS
|
||||
puts("Creating GUS");
|
||||
GUS_OnReset();
|
||||
GUS_SetAudioBuffer(settings.GUS.audioBuffer);
|
||||
GUS_SetDMAInterval(settings.GUS.dmaInterval);
|
||||
GUS_SetFixed44k(settings.GUS.force44k);
|
||||
multicore_launch_core1(&play_gus);
|
||||
#endif // SOUND_GUS
|
||||
|
||||
@@ -995,18 +970,16 @@ int main()
|
||||
pwm_init(1, &pwm_c, true);
|
||||
pwm_init(2, &pwm_c, true);
|
||||
pwm_init(3, &pwm_c, true);
|
||||
#ifdef USB_JOYSTICK_ONLY
|
||||
multicore_launch_core1(&play_usb);
|
||||
#endif // USB_JOYSTICK_ONLY
|
||||
#endif // USB_JOYSTICK
|
||||
|
||||
#ifdef USB_MOUSE
|
||||
puts("Config USB Mouse emulation");
|
||||
uartemu_init(mousePort);
|
||||
sermouse_init();
|
||||
uartemu_init(0);
|
||||
sermouse_init(settings.Mouse.protocol, settings.Mouse.reportRate, settings.Mouse.sensitivity);
|
||||
sermouse_attach_uart();
|
||||
multicore_launch_core1(&play_usb);
|
||||
#endif // USB_MOUSE
|
||||
#ifdef USB_ONLY
|
||||
multicore_launch_core1(&play_usb);
|
||||
#endif // USBONLY
|
||||
|
||||
for(int i=AD0_PIN; i<(AD0_PIN + 10); ++i) {
|
||||
gpio_disable_pulls(i);
|
||||
@@ -1061,18 +1034,16 @@ int main()
|
||||
PIC_Init();
|
||||
#endif
|
||||
|
||||
processSettings();
|
||||
|
||||
for (;;) {
|
||||
#ifndef USE_IRQ
|
||||
// if (!pio_sm_is_rx_fifo_empty(pio0, IOW_PIO_SM)) {
|
||||
if (iow_has_data()) {
|
||||
handle_iow();
|
||||
// gpio_xor_mask(LED_PIN);
|
||||
}
|
||||
|
||||
// if (!pio_sm_is_rx_fifo_empty(pio0, IOR_PIO_SM)) {
|
||||
if (ior_has_data()) {
|
||||
handle_ior();
|
||||
// gpio_xor_mask(LED_PIN);
|
||||
}
|
||||
#endif
|
||||
#ifndef USE_ALARM
|
||||
|
||||
+25
-6
@@ -22,22 +22,28 @@
|
||||
extern "C" void OPL_Pico_simple(int16_t *buffer, uint32_t nsamples);
|
||||
extern "C" void OPL_Pico_PortWrite(opl_port_t, unsigned int);
|
||||
|
||||
#ifdef SOUND_SB
|
||||
extern int16_t sbdsp_sample();
|
||||
#ifdef USE_ALARM
|
||||
#include "pico_pic.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "clamp.h"
|
||||
|
||||
#include "cmd_buffers.h"
|
||||
extern cms_buffer_t opl_buffer;
|
||||
|
||||
#ifdef USB_JOYSTICK
|
||||
#ifdef USB_STACK
|
||||
#include "tusb.h"
|
||||
#endif
|
||||
#ifdef USB_MOUSE
|
||||
#include "mouse/8250uart.h"
|
||||
#include "mouse/sermouse.h"
|
||||
#endif
|
||||
|
||||
extern uint LED_PIN;
|
||||
|
||||
#ifdef USE_ALARM
|
||||
#include "pico_pic.h"
|
||||
#endif
|
||||
|
||||
#if PICO_ON_DEVICE
|
||||
#include "pico/binary_info.h"
|
||||
@@ -93,12 +99,14 @@ void play_adlib() {
|
||||
flash_safe_execute_core_init();
|
||||
uint32_t start, end;
|
||||
|
||||
#ifdef SOUND_SB
|
||||
#ifdef USE_ALARM
|
||||
// Init PIC on this core so it handles timers
|
||||
PIC_Init();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USB_JOYSTICK
|
||||
#ifdef USB_STACK
|
||||
// Init TinyUSB for joystick support
|
||||
tuh_init(BOARD_TUH_RHPORT);
|
||||
#endif
|
||||
@@ -125,13 +133,24 @@ void play_adlib() {
|
||||
int16_t *samples = (int16_t *) buffer->buffer->bytes;
|
||||
int16_t opl_sample;
|
||||
OPL_Pico_simple(&opl_sample, 1);
|
||||
#ifdef SOUND_SB
|
||||
samples[0] = samples[1] = clamp16((int32_t)sbdsp_sample() + (int32_t)opl_sample);
|
||||
#else
|
||||
samples[0] = samples[1] = opl_sample;
|
||||
#endif
|
||||
buffer->sample_count=1;
|
||||
// putchar((unsigned char)buffer->buffer->bytes[1]);
|
||||
give_audio_buffer(ap, buffer);
|
||||
#ifdef USB_JOYSTICK
|
||||
#ifdef USB_STACK
|
||||
// Service TinyUSB events
|
||||
tuh_task();
|
||||
#endif
|
||||
#ifdef USB_MOUSE
|
||||
// mouse task
|
||||
sermouse_core1_task();
|
||||
|
||||
// uart emulation task
|
||||
uartemu_core1_task();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
+14
-3
@@ -25,9 +25,13 @@ extern tandy_buffer_t tandy_buffer;
|
||||
|
||||
extern uint LED_PIN;
|
||||
|
||||
#ifdef USB_JOYSTICK
|
||||
#ifdef USB_STACK
|
||||
#include "tusb.h"
|
||||
#endif
|
||||
#ifdef USB_MOUSE
|
||||
#include "mouse/8250uart.h"
|
||||
#include "mouse/sermouse.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -76,7 +80,7 @@ struct audio_buffer_pool *init_audio() {
|
||||
void play_tandy() {
|
||||
puts("starting core 1 tandy");
|
||||
flash_safe_execute_core_init();
|
||||
#ifdef USB_JOYSTICK
|
||||
#ifdef USB_STACK
|
||||
// Init TinyUSB for joystick support
|
||||
tuh_init(BOARD_TUH_RHPORT);
|
||||
#endif
|
||||
@@ -119,9 +123,16 @@ void play_tandy() {
|
||||
buffer->sample_count = SAMPLES_PER_BUFFER;
|
||||
|
||||
give_audio_buffer(ap, buffer);
|
||||
#ifdef USB_JOYSTICK
|
||||
#ifdef USB_STACK
|
||||
// Service TinyUSB events
|
||||
tuh_task();
|
||||
#endif
|
||||
#ifdef USB_MOUSE
|
||||
// mouse task
|
||||
sermouse_core1_task();
|
||||
|
||||
// uart emulation task
|
||||
uartemu_core1_task();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,37 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "tusb.h"
|
||||
#include "mouse/8250uart.h"
|
||||
#include "mouse/sermouse.h"
|
||||
|
||||
// #include <string.h>
|
||||
|
||||
#ifdef USE_ALARM
|
||||
#include "pico_pic.h"
|
||||
#endif
|
||||
|
||||
void play_usb() {
|
||||
puts("starting core 1 USB");
|
||||
|
||||
// board_init();
|
||||
|
||||
#ifdef USE_ALARM
|
||||
// Init PIC on this core so it handles timers
|
||||
PIC_Init();
|
||||
puts("pic inited on core 1");
|
||||
#endif
|
||||
|
||||
// init host stack on configured roothub port
|
||||
tuh_init(BOARD_TUH_RHPORT);
|
||||
|
||||
for (;;) {
|
||||
// tinyusb host task
|
||||
tuh_task();
|
||||
|
||||
// mouse task
|
||||
sermouse_core1_task();
|
||||
|
||||
// uart emulation task
|
||||
uartemu_core1_task();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user