analog/v2-analog-rev1/common/config.c
David Kuder f7d4779880 Build 0159
Progress on PCPI mode bug fixes. PCPI mode is now working again, but the config interface is still broken enough to prevent the use of the config utility while in this mode.. Sending the FORMAT command from the monitor rom returns the card to defaults.
Replace n with the slot number the card is installed in:

Correction of mousetext / inverse / flashing handling on IIe
see https://github.com/V2RetroComputing/analog/issues/3

]CALL -151
*CnF0:46 4F 52 4D 41 54 00 00

Monochrome mode & color palettes are now implemented.
$C0n1: Monochrome mode & palette
  $80: B&W
  $90: Inverse
  $A0: Amber
  $B0: Inverse Amber
  $C0: Green
  $D0: Inverse Green
  $E0: Commodore 64 Theme
  $F0: Use IIgs palette
$C0n2: Mirror of IIgs TBCOLOR register
$C0n3: Mirror of IIgs BORDER register
2023-03-02 11:05:44 -05:00

363 lines
10 KiB
C

#include "common/config.h"
#include "common/buffers.h"
#include "common/flash.h"
#include "pico_hal.h"
volatile v2mode_t cfg_mode = MODE_UNKNOWN;
volatile v2mode_t current_mode = MODE_UNKNOWN;
volatile usbmux_t usbmux;
volatile serialmux_t serialmux;
volatile wifimode_t wifimode;
volatile compat_t cfg_machine = MACHINE_AUTO;
volatile compat_t current_machine = MACHINE_AUTO;
volatile uint8_t wifi_ssid[32];
volatile uint8_t wifi_psk[32];
extern volatile bool userfont;
char ERR_READY[8] = { 'R', 'E', 'A', 'D', 'Y', 0, 0, 0 };
char ERR_EOF[8] = { 'E', 'O', 'F', 0, 0, 0, 0, 0 };
char ERR_NOFILE[8] = { 'E', 'O', 'F', 0, 0, 0, 0, 0 };
void parse_config(uint8_t *buffer) {
if(!memcmp("C=", buffer, 2)) {
if(!strcmp("DIAG", buffer+2)) {
cfg_mode = MODE_DIAG;
} else if(!strcmp("FS", buffer+2)) {
cfg_mode = MODE_FS;
} else if(!strcmp("VGA", buffer+2)) {
cfg_mode = MODE_VGACARD;
} else if(!strcmp("Z80", buffer+2)) {
cfg_mode = MODE_APPLICARD;
} else if(!strcmp("SER", buffer+2)) {
cfg_mode = MODE_SERIAL;
} else if(!strcmp("PAR", buffer+2)) {
cfg_mode = MODE_PARALLEL;
} else if(!strcmp("SNES", buffer+2)) {
cfg_mode = MODE_SNESMAX;
}
} else if(!memcmp("H=", buffer, 2)) {
if(!strcmp("AUTO", buffer+2)) {
cfg_machine = MACHINE_AUTO;
} else if(!strcmp("II", buffer+2)) {
cfg_machine = MACHINE_II;
internal_flags &= ~(IFLAGS_IIE_REGS | IFLAGS_IIGS_REGS);
} else if(!strcmp("IIE", buffer+2)) {
cfg_machine = MACHINE_IIE;
internal_flags &= ~IFLAGS_IIGS_REGS;
internal_flags |= IFLAGS_IIE_REGS;
} else if(!strcmp("IIGS", buffer+2)) {
cfg_machine = MACHINE_IIGS;
internal_flags |= IFLAGS_IIE_REGS | IFLAGS_IIGS_REGS;
} else if(!strcmp("PRAVETZ", buffer+2)) {
cfg_machine = MACHINE_PRAVETZ;
internal_flags &= ~(IFLAGS_IIE_REGS | IFLAGS_IIGS_REGS);
}
} else if(!memcmp("S=", buffer, 2)) {
if(!strcmp("USB", buffer+2)) {
serialmux = SERIAL_USB;
} else if(!strcmp("WIFI", buffer+2)) {
serialmux = SERIAL_WIFI;
} else if(!strcmp("PRN", buffer+2)) {
serialmux = SERIAL_PRINTER;
} else if(!strcmp("LOOP", buffer+2)) {
serialmux = SERIAL_LOOP;
}
} else if(!memcmp("U=", buffer, 2)) {
if(!strcmp("CG", buffer+2)) {
usbmux = USB_GUEST_CDC;
} else if(!strcmp("CH", buffer+2)) {
usbmux = USB_HOST_CDC;
}
} else if(!memcmp("W=", buffer, 2)) {
if(!strcmp("C", buffer+2)) {
wifimode = WIFI_CLIENT;
} else if(!strcmp("A", buffer+2)) {
wifimode = WIFI_AP;
}
} else if(!memcmp("WN=", buffer, 3)) {
strncpy((char*)wifi_ssid, buffer+5, 24);
} else if(!memcmp("WP=", buffer, 3)) {
strncpy((char*)wifi_psk, buffer+5, 24);
}
}
void default_config() {
cfg_mode = MODE_VGACARD;
serialmux = SERIAL_LOOP;
usbmux = USB_GUEST_CDC;
wifimode = WIFI_AP;
strcpy((char*)wifi_ssid, "V2RetroNet");
strcpy((char*)wifi_psk, "Analog");
cfg_machine = MACHINE_AUTO;
}
int make_config(uint8_t *buf, uint16_t len) {
uint16_t ptr = 0;
memset(buf, 0, len);
switch(cfg_mode) {
default:
case MODE_VGACARD:
strcpy(buf+ptr, "C=VGA");
ptr += 32;
break;
case MODE_APPLICARD:
strcpy(buf+ptr, "C=Z80");
ptr += 32;
break;
case MODE_SERIAL:
strcpy(buf+ptr, "C=SER");
ptr += 32;
break;
case MODE_PARALLEL:
strcpy(buf+ptr, "C=PAR");
ptr += 32;
break;
case MODE_SNESMAX:
strcpy(buf+ptr, "C=SNES");
ptr += 32;
break;
case MODE_ETHERNET:
strcpy(buf+ptr, "C=NET");
ptr += 32;
break;
case MODE_FS:
strcpy(buf+ptr, "C=FS");
ptr += 32;
break;
}
switch(cfg_machine) {
default:
case MACHINE_AUTO:
strcpy(buf+ptr, "H=AUTO");
ptr += 32;
break;
case MACHINE_II:
strcpy(buf+ptr, "H=II");
ptr += 32;
break;
case MACHINE_IIE:
strcpy(buf+ptr, "H=IIE");
ptr += 32;
break;
case MACHINE_IIGS:
strcpy(buf+ptr, "H=IIGS");
ptr += 32;
break;
}
switch(serialmux) {
default:
case SERIAL_LOOP:
strcpy(buf+ptr, "M=LOOP");
ptr += 32;
break;
case SERIAL_USB:
strcpy(buf+ptr, "M=USB");
ptr += 32;
break;
case SERIAL_WIFI:
strcpy(buf+ptr, "M=WIFI");
ptr += 32;
break;
case SERIAL_PRINTER:
strcpy(buf+ptr, "M=PRN");
ptr += 32;
break;
}
switch(usbmux) {
case USB_GUEST_CDC:
strcpy(buf+ptr, "U=CG");
ptr += 32;
break;
case USB_HOST_CDC:
strcpy(buf+ptr, "U=CH");
ptr += 32;
break;
}
switch(wifimode) {
case WIFI_CLIENT:
strcpy(buf+ptr, "W=C");
ptr += 32;
break;
case WIFI_AP:
strcpy(buf+ptr, "W=A");
ptr += 32;
break;
}
strcpy(buf+ptr, "WS=");
strncpy(buf+ptr+2, (char*)wifi_ssid, 24);
ptr += 32;
strcpy(buf+ptr, "WP=");
strncpy(buf+ptr+2, (char*)wifi_psk, 24);
ptr += 32;
return ptr;
}
void write_config() {
uint8_t config_temp[1024];
int config_len;
config_len = make_config(config_temp, sizeof(config_temp));
int file = pico_open("config", LFS_O_WRONLY | LFS_O_CREAT);
if(file < 0)
return;
pico_write(file, config_temp, config_len);
pico_close(file);
}
void read_config() {
uint8_t config_temp[1024];
int file = pico_open("config", LFS_O_RDONLY);
int config_len = 0;
if(file < 0)
return;
memset(config_temp, 0, sizeof(config_temp));
config_len = pico_read(file, config_temp, sizeof(config_temp));
pico_close(file);
if(config_len > 0) {
for(int ptr = 0; ptr < config_len; ptr+=32) {
parse_config(config_temp+ptr);
}
}
}
extern uint8_t character_rom[2048];
void upload_config() {
int file = pico_open("config", LFS_O_RDONLY);
memset((uint8_t*)(apple_memory + 0xC800), 0, 1024);
if(file < 0) {
make_config((uint8_t*)(apple_memory + 0xC800), 1024);
} else {
pico_read(file, (uint8_t*)(apple_memory + 0xC800), 1024);
pico_close(file);
}
memcpy(config_errbuf, ERR_READY, sizeof(ERR_READY));
}
void download_config(uint16_t ptr) {
int file = pico_open("config", LFS_O_WRONLY | LFS_O_CREAT);
if(file < 0) {
memcpy(config_errbuf, ERR_NOFILE, sizeof(ERR_NOFILE));
return;
}
pico_write(file, (uint8_t*)(apple_memory + ptr), 1024);
pico_close(file);
memcpy(config_errbuf, ERR_READY, sizeof(ERR_READY));
}
void upload_font(uint8_t page) {
int file;
if(page > 1) {
memcpy(config_errbuf, ERR_EOF, sizeof(ERR_EOF));
return;
}
file = pico_open("font", LFS_O_RDONLY);
if(file < 0) {
memcpy((uint8_t*)(apple_memory + 0xC800), (character_rom + (1024*page)), 1024);
} else {
pico_lseek(file, 1024 * page, LFS_SEEK_SET);
pico_read(file, (uint8_t*)(apple_memory + 0xC800), 1024);
pico_close(file);
}
memcpy(config_errbuf, ERR_READY, sizeof(ERR_READY));
}
void download_font(uint16_t ptr) {
int file = pico_open("font", LFS_O_WRONLY | LFS_O_CREAT);
memcpy(character_rom, (uint8_t*)(apple_memory + ptr), 2048);
if(file < 0) {
memcpy(config_errbuf, ERR_NOFILE, sizeof(ERR_NOFILE));
return;
}
pico_write(file, (uint8_t*)(apple_memory + ptr), 2048);
pico_close(file);
memcpy(config_errbuf, ERR_READY, sizeof(ERR_READY));
}
void config_format() {
pico_unmount();
if(pico_mount(1) != LFS_ERR_OK) {
memcpy(config_errbuf, ERR_NOFILE, sizeof(ERR_NOFILE));
} else {
memcpy(config_errbuf, ERR_READY, sizeof(ERR_READY));
}
}
void config_handler() {
if(config_cmdbuf[7] != 0) return;
config_cmdbuf[7] = 0xff;
if(!memcmp("H=", (uint8_t*)config_cmdbuf, 2)) {
if(!strcmp("II", config_cmdbuf+2)) {
current_machine = MACHINE_II;
internal_flags &= ~(IFLAGS_IIE_REGS | IFLAGS_IIGS_REGS);
} else if(!strcmp("IIE", config_cmdbuf+2)) {
current_machine = MACHINE_IIE;
internal_flags &= ~IFLAGS_IIGS_REGS;
internal_flags |= IFLAGS_IIE_REGS;
} else if(!strcmp("IIGS", config_cmdbuf+2)) {
current_machine = MACHINE_IIGS;
internal_flags |= IFLAGS_IIE_REGS | IFLAGS_IIGS_REGS;
#if 0
} else if(!strcmp("B108", config_cmdbuf+2)) {
current_machine = MACHINE_BASIS;
internal_flags &= ~(IFLAGS_IIE_REGS | IFLAGS_IIGS_REGS);
} else if(!strcmp("P", config_cmdbuf+2)) {
current_machine = MACHINE_PRAVETZ;
internal_flags &= ~(IFLAGS_IIE_REGS | IFLAGS_IIGS_REGS);
} else if(!strcmp("A7", config_cmdbuf+2)) {
current_machine = MACHINE_AGAT7;
internal_flags &= ~(IFLAGS_IIE_REGS | IFLAGS_IIGS_REGS);
} else if(!strcmp("A9", config_cmdbuf+2)) {
current_machine = MACHINE_AGAT9;
internal_flags &= ~(IFLAGS_IIE_REGS | IFLAGS_IIGS_REGS);
#endif
}
} else if(!memcmp("UF", (uint8_t*)config_cmdbuf, 2)) {
upload_font(config_cmdbuf[2]);
} else if(!memcmp("DF", (uint8_t*)config_cmdbuf, 2)) {
download_font((config_cmdbuf[2] << 0) | (config_cmdbuf[3] << 8));
flash_reboot();
} else if(!memcmp("UC", (uint8_t*)config_cmdbuf, 2)) {
upload_config();
} else if(!memcmp("DC", (uint8_t*)config_cmdbuf, 2)) {
download_config((config_cmdbuf[2] << 0) | (config_cmdbuf[3] << 8));
flash_reboot();
} else if(!memcmp("FORMAT", (uint8_t*)config_cmdbuf, 6)) {
config_format();
flash_reboot();
} else if(!memcmp("RB", (uint8_t*)config_cmdbuf, 2)) {
flash_reboot();
}
memset(config_cmdbuf, 0x00, 7);
}