mirror of
https://github.com/polpo/picogus.git
synced 2026-10-25 21:40:16 +00:00
CD image handling
This commit is contained in:
1 parent
dd43203219
commit
a7484c5b04
18 files changed
+589
-156
No files matched your search
@@ -99,7 +99,7 @@ jobs:
|
||||
working-directory: ${{github.workspace}}/pgusinit
|
||||
run: |
|
||||
mkdir -p $OUTPUT_DIR
|
||||
make -f Makefile-cross INCLUDE="$WATCOM"/h
|
||||
make INCLUDE="$WATCOM"/h
|
||||
cp pgusinit.exe $OUTPUT_DIR
|
||||
|
||||
# will generate pgusinit.zip as downloadable artifact with pgusinit.exe
|
||||
|
||||
@@ -53,23 +53,34 @@ static const char *modenames[9] = {
|
||||
#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_NE2KPORT 0x50 // NE2000 Base port
|
||||
#define MODE_WIFISSID 0x51 // WiFi SSID
|
||||
#define MODE_WIFIPASS 0x52 // WiFi password
|
||||
#define MODE_WIFIAPPLY 0x53 // apply WiFi settings
|
||||
#define MODE_WIFISTAT 0x54 // WiFi status
|
||||
|
||||
#define MODE_CDPORT 0x60 // CD base port
|
||||
#define MODE_CDSTATUS 0x61 // Get CD image command status
|
||||
#define MODE_CDIMAGES 0x62 // List CD images
|
||||
#define MODE_CDLOAD 0x63 // Load CD image or get loaded image
|
||||
#define MODE_CDSELECT 0x64 // Select next/prev loaded image
|
||||
|
||||
#define MODE_DEFAULTS 0xE0 // Select reset to defaults register
|
||||
#define MODE_SAVE 0xE1 // Select save settings register
|
||||
#define MODE_REBOOT 0xE2 // Select reboot register
|
||||
|
||||
Executable → Regular
+6
-14
@@ -1,16 +1,8 @@
|
||||
obj = pgusinit.obj
|
||||
bin = pgusinit.exe
|
||||
CC = wcl
|
||||
CFLAGS = -bcl=dos -za99 -os
|
||||
|
||||
CC = wcc
|
||||
CFLAGS = -za99
|
||||
LD = wlink
|
||||
pgusinit.exe: pgusinit.c
|
||||
$(CC) $(CFLAGS) $<
|
||||
|
||||
$(bin): $(obj)
|
||||
$(LD) name $@ file { $(obj) }
|
||||
|
||||
.c.obj:
|
||||
$(CC) -fo=$@ $(CFLAGS) $<
|
||||
|
||||
clean: .symbolic
|
||||
del *.obj
|
||||
del $(bin)
|
||||
clean:
|
||||
rm -f pgusinit.o pgusinit.exe
|
||||
@@ -1,8 +0,0 @@
|
||||
CC = wcl
|
||||
CFLAGS = -bcl=dos -za99 -os
|
||||
|
||||
pgusinit.exe: pgusinit.c
|
||||
$(CC) $(CFLAGS) $<
|
||||
|
||||
clean:
|
||||
rm -f pgusinit.o pgusinit.exe
|
||||
+107
-36
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022-2024 Ian Scott
|
||||
* Copyright (C) 2022-2025 Ian Scott
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -27,11 +27,11 @@
|
||||
#include "../common/picogus.h"
|
||||
|
||||
static void banner(void) {
|
||||
printf("PicoGUSinit v3.3.0 (c) 2024 Ian Scott - licensed under the GNU GPL v2\n");
|
||||
printf("PicoGUSinit v3.4.0 (c) 2025 Ian Scott - licensed under the GNU GPL v2\n");
|
||||
}
|
||||
|
||||
|
||||
static void usage(char *argv0, card_mode_t mode, bool print_all) {
|
||||
static void usage(card_mode_t mode, bool print_all) {
|
||||
// Max line length @ 80 chars:
|
||||
// "................................................................................\n"
|
||||
printf("Usage:\n");
|
||||
@@ -216,7 +216,7 @@ static void print_firmware_string(void) {
|
||||
outp(CONTROL_PORT, MODE_FWSTRING); // Select firmware string register
|
||||
|
||||
char firmware_string[256] = {0};
|
||||
for (int i = 0; i < 255; ++i) {
|
||||
for (uint8_t i = 0; i < 255; ++i) {
|
||||
firmware_string[i] = inp(DATA_PORT_HIGH);
|
||||
if (!firmware_string[i]) {
|
||||
break;
|
||||
@@ -235,6 +235,54 @@ static bool wait_for_read(const uint8_t value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool print_cdimage_list(void) {
|
||||
outp(CONTROL_PORT, 0xCC); // Knock on the door...
|
||||
outp(CONTROL_PORT, MODE_CDLOAD); // Get currently loaded index
|
||||
uint8_t current_index = inp(DATA_PORT_HIGH);
|
||||
printf("Listing CD images on USB drive:\n");
|
||||
outp(CONTROL_PORT, 0xCC); // Knock on the door...
|
||||
outp(CONTROL_PORT, MODE_CDIMAGES); // Select CD image list register
|
||||
delay(10);
|
||||
outp(CONTROL_PORT, 0xCC); // Knock on the door...
|
||||
outp(CONTROL_PORT, MODE_CDSTATUS); // Select CD image status register
|
||||
bool ready = false;
|
||||
for (uint16_t i = 0; i < 65535; ++i) {
|
||||
int8_t cd_status = inp(DATA_PORT_HIGH);
|
||||
if (cd_status == -1) {
|
||||
printf("Error getting CD image list\n");
|
||||
return false;
|
||||
} else if (cd_status == 2) {
|
||||
ready = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ready) {
|
||||
printf("Timeout getting CD image list\n");
|
||||
return false;
|
||||
}
|
||||
outp(CONTROL_PORT, 0xCC); // Knock on the door...
|
||||
outp(CONTROL_PORT, MODE_CDIMAGES); // Select CD image list register
|
||||
char b[256], c, *p = b;
|
||||
uint8_t line = 1;
|
||||
while ((c = inp(DATA_PORT_HIGH)) != 4 /* ASCII EOT */) {
|
||||
*p++ = c;
|
||||
if (!c) {
|
||||
putchar(current_index == line ? '*' : ' ');
|
||||
printf(" %2d: %s\n", line++, b);
|
||||
p = b;
|
||||
}
|
||||
}
|
||||
if (current_index) {
|
||||
printf("Currently loaded image marked with \"*\".\n");
|
||||
} else {
|
||||
printf("No image currently loaded.\n");
|
||||
}
|
||||
printf("Run \"pgusinit /cdload n\" to load the nth image in the above list.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static void write_settings(void) {
|
||||
outp(CONTROL_PORT, MODE_SAVE); // Select save settings register
|
||||
outp(DATA_PORT_HIGH, 0xff);
|
||||
@@ -403,7 +451,7 @@ static void send_string(uint8_t mode, char* str, int16_t max_len)
|
||||
outp(CONTROL_PORT, 0xCC); // Knock on the door...
|
||||
outp(CONTROL_PORT, mode);
|
||||
char chr;
|
||||
for (int i = 0; i < max_len; ++i) {
|
||||
for (int16_t i = 0; i < max_len; ++i) {
|
||||
if (str[i] == 0) { // End of string
|
||||
break;
|
||||
}
|
||||
@@ -414,12 +462,12 @@ static void send_string(uint8_t mode, char* str, int16_t max_len)
|
||||
|
||||
#define process_bool_opt(option) \
|
||||
if (i + 1 >= argc) { \
|
||||
usage(argv[0], mode, false); \
|
||||
usage(mode, false); \
|
||||
return 255; \
|
||||
} \
|
||||
e = sscanf(argv[++i], "%1[01]", tmp_arg); \
|
||||
if (e != 1) { \
|
||||
usage(argv[0], mode, false); \
|
||||
usage(mode, false); \
|
||||
return 5; \
|
||||
} \
|
||||
option = (tmp_arg[0] == '1') ? 1 : 0;
|
||||
@@ -427,12 +475,12 @@ option = (tmp_arg[0] == '1') ? 1 : 0;
|
||||
|
||||
#define process_port_opt(option) \
|
||||
if (i + 1 >= argc) { \
|
||||
usage(argv[0], mode, false); \
|
||||
usage(mode, false); \
|
||||
return 255; \
|
||||
} \
|
||||
e = sscanf(argv[++i], "%hx", &option); \
|
||||
if (e != 1 || option > 0x3ffu) { \
|
||||
usage(argv[0], mode, false); \
|
||||
usage(mode, false); \
|
||||
return 4; \
|
||||
}
|
||||
|
||||
@@ -465,12 +513,12 @@ int main(int argc, char* argv[]) {
|
||||
while (i < argc) {
|
||||
if (stricmp(argv[i], "/flash") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], INVALID_MODE, false);
|
||||
usage(INVALID_MODE, false);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%255s", fw_filename);
|
||||
if (e != 1) {
|
||||
usage(argv[0], INVALID_MODE, false);
|
||||
usage(INVALID_MODE, false);
|
||||
return 5;
|
||||
}
|
||||
return write_firmware(fw_filename);
|
||||
@@ -495,10 +543,10 @@ int main(int argc, char* argv[]) {
|
||||
while (i < argc) {
|
||||
// global options /////////////////////////////////////////////////////////////////
|
||||
if (stricmp(argv[i], "/?") == 0) {
|
||||
usage(argv[0], mode, false);
|
||||
usage(mode, false);
|
||||
return 0;
|
||||
} else if (stricmp(argv[i], "/??") == 0) {
|
||||
usage(argv[0], mode, true);
|
||||
usage(mode, true);
|
||||
return 0;
|
||||
} else if (stricmp(argv[i], "/joy") == 0) {
|
||||
process_bool_opt(tmp_uint8);
|
||||
@@ -506,22 +554,22 @@ int main(int argc, char* argv[]) {
|
||||
outp(DATA_PORT_HIGH, tmp_uint8);
|
||||
} else if (stricmp(argv[i], "/mode") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode, false);
|
||||
usage(mode, false);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%7s", mode_name);
|
||||
if (e != 1) {
|
||||
usage(argv[0], mode, false);
|
||||
usage(mode, false);
|
||||
return 5;
|
||||
}
|
||||
} else if (stricmp(argv[i], "/wtvol") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode, false);
|
||||
usage(mode, false);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%hhu", &tmp_uint8);
|
||||
if (e != 1 || tmp_uint8 > 100) {
|
||||
usage(argv[0], mode, false);
|
||||
usage(mode, false);
|
||||
return 4;
|
||||
}
|
||||
outp(CONTROL_PORT, MODE_WTVOL); // Select wavetable volume register
|
||||
@@ -538,24 +586,24 @@ int main(int argc, char* argv[]) {
|
||||
outp(DATA_PORT_HIGH, tmp_uint8);
|
||||
} else if (stricmp(argv[i], "/gusbuf") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode, false);
|
||||
usage(mode, false);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%hhu", &tmp_uint8);
|
||||
if (e != 1 || tmp_uint8 < 1) {
|
||||
usage(argv[0], mode, false);
|
||||
usage(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);
|
||||
usage(mode, false);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%hhu", &tmp_uint8);
|
||||
if (e != 1) {
|
||||
usage(argv[0], mode, false);
|
||||
usage(mode, false);
|
||||
return 4;
|
||||
}
|
||||
outp(CONTROL_PORT, MODE_GUSDMA); // Select DMA interval register
|
||||
@@ -603,12 +651,12 @@ int main(int argc, char* argv[]) {
|
||||
// Mouse options /////////////////////////////////////////////////////////////////
|
||||
} else if (stricmp(argv[i], "/mousecom") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode, false);
|
||||
usage(mode, false);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%hhu", &tmp_uint8);
|
||||
if (e != 1 || tmp_uint8 > 3) {
|
||||
usage(argv[0], mode, false);
|
||||
usage(mode, false);
|
||||
return 4;
|
||||
}
|
||||
switch (tmp_uint8) {
|
||||
@@ -628,43 +676,43 @@ int main(int argc, char* argv[]) {
|
||||
tmp_uint16 = 0x2e8;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0], mode, false);
|
||||
usage(mode, false);
|
||||
return 4;
|
||||
}
|
||||
outp(CONTROL_PORT, MODE_MOUSEPORT); // Select mouse port register
|
||||
outpw(DATA_PORT_LOW, tmp_uint16);
|
||||
} else if (stricmp(argv[i], "/mousesen") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode, false);
|
||||
usage(mode, false);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%hi", &tmp_uint16);
|
||||
if (e != 1) {
|
||||
usage(argv[0], mode, false);
|
||||
usage(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);
|
||||
usage(mode, false);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%hhu", &tmp_uint8);
|
||||
if (e != 1 || tmp_uint8 > 3) {
|
||||
usage(argv[0], mode, false);
|
||||
usage(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);
|
||||
usage(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);
|
||||
usage(mode, false);
|
||||
return 4;
|
||||
}
|
||||
outp(CONTROL_PORT, MODE_MOUSERATE);
|
||||
@@ -678,32 +726,55 @@ int main(int argc, char* argv[]) {
|
||||
wifi_printStatus();
|
||||
} else if (stricmp(argv[i], "/wifissid") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode, false);
|
||||
usage(mode, false);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%32s", wifi_ssid);
|
||||
if (e != 1) {
|
||||
usage(argv[0], mode, false);
|
||||
usage(mode, false);
|
||||
return 4;
|
||||
}
|
||||
send_string(MODE_WIFISSID, wifi_ssid, 32);
|
||||
} else if (stricmp(argv[i], "/wifipass") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(argv[0], mode, false);
|
||||
usage(mode, false);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%63s", wifi_pass);
|
||||
if (e != 1) {
|
||||
usage(argv[0], mode, false);
|
||||
usage(mode, false);
|
||||
return 4;
|
||||
}
|
||||
send_string(MODE_WIFIPASS, wifi_pass, 63);
|
||||
} else if (stricmp(argv[i], "/wifinopass") == 0) {
|
||||
nopass = true;
|
||||
send_string(MODE_WIFIPASS, "", 1);
|
||||
// CD-ROM options /////////////////////////////////////////////////////////////////
|
||||
} else if (stricmp(argv[i], "/cdport") == 0) {
|
||||
process_port_opt(tmp_uint16);
|
||||
outp(CONTROL_PORT, MODE_CDPORT); // Select Tandy port register
|
||||
outpw(DATA_PORT_LOW, tmp_uint16); // Write port
|
||||
} else if (stricmp(argv[i], "/cdlist") == 0) {
|
||||
if (!print_cdimage_list()) {
|
||||
return 98;
|
||||
}
|
||||
return 0;
|
||||
} else if (stricmp(argv[i], "/cdload") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
usage(mode, false);
|
||||
return 255;
|
||||
}
|
||||
e = sscanf(argv[++i], "%hhu", &tmp_uint8);
|
||||
if (e != 1) {
|
||||
usage(mode, false);
|
||||
return 3;
|
||||
}
|
||||
outp(CONTROL_PORT, MODE_CDLOAD); // Select audio buffer register
|
||||
outp(DATA_PORT_HIGH, tmp_uint8);
|
||||
return 0;
|
||||
} else {
|
||||
printf("Unknown option: %s\n", argv[i]);
|
||||
usage(argv[0], mode, false);
|
||||
usage(mode, false);
|
||||
return 255;
|
||||
}
|
||||
++i;
|
||||
@@ -719,7 +790,7 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
}
|
||||
if (i == 8) {
|
||||
usage(argv[0], mode, false);
|
||||
usage(mode, false);
|
||||
return 255;
|
||||
}
|
||||
return reboot_to_firmware(fw_num, permanent);
|
||||
|
||||
@@ -3,7 +3,7 @@ add_library(cdrom INTERFACE)
|
||||
target_sources(cdrom INTERFACE
|
||||
${CMAKE_CURRENT_LIST_DIR}/cdrom.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/cdrom_image_backend.c
|
||||
#${CMAKE_CURRENT_LIST_DIR}/cdrom_image_viso.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/cdrom_image_manager.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/cdrom_image.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/86box_compat.c
|
||||
)
|
||||
|
||||
+33
-16
@@ -29,11 +29,11 @@
|
||||
#include "86box_compat.h"
|
||||
#include "cdrom.h"
|
||||
#include "cdrom_image.h"
|
||||
#include "cdrom_image_manager.h"
|
||||
#include "pico/multicore.h"
|
||||
#include "hardware/structs/timer.h"
|
||||
|
||||
|
||||
|
||||
/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong:
|
||||
there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start
|
||||
of the audio while audio still plays. With an absolute conversion, the counter is fine. */
|
||||
@@ -139,27 +139,43 @@ bcd2bin(uint8_t x)
|
||||
}
|
||||
*/
|
||||
|
||||
void cdrom_tasks(cdrom_t *dev) {
|
||||
if(dev->req_image_load) {
|
||||
if(dev->disk_loaded) {
|
||||
dev->disk_loaded=0;
|
||||
dev->media_changed=1;
|
||||
void cdrom_tasks(cdrom_t *dev) {
|
||||
// Will almost always be CD_COMMAND_NONE, so use __builtin_expect to tell the compiler
|
||||
switch (__builtin_expect(dev->image_command, CD_COMMAND_NONE)) {
|
||||
case CD_COMMAND_NONE:
|
||||
cdrom_read_data(dev);
|
||||
break;
|
||||
case CD_COMMAND_IMAGE_LIST:
|
||||
dev->image_list = cdman_list_images(&dev->image_count);
|
||||
dev->image_command = CD_COMMAND_NONE;
|
||||
dev->image_status = dev->image_list ? CD_STATUS_READY : CD_STATUS_ERROR;
|
||||
break;
|
||||
case CD_COMMAND_IMAGE_LOAD_INDEX:
|
||||
cdman_load_image_index(dev, dev->image_data);
|
||||
break;
|
||||
case CD_COMMAND_IMAGE_LOAD:
|
||||
printf("loading");
|
||||
if (dev->disk_loaded) {
|
||||
dev->disk_loaded = 0;
|
||||
dev->media_changed = 1;
|
||||
cdrom_image_close(dev);
|
||||
printf("Disk Removed.\n");
|
||||
cdrom_error(dev,0x11); //media changed
|
||||
cdrom_error(dev, 0x11); //media changed
|
||||
}
|
||||
if(dev->image_path[0]) {
|
||||
if (dev->image_path[0]) {
|
||||
printf("Opening %s...",dev->image_path);
|
||||
cdrom_image_open(dev,dev->image_path);
|
||||
if (cdrom_image_open(dev,dev->image_path)) {
|
||||
dev->image_status = CD_STATUS_ERROR;
|
||||
break;
|
||||
}
|
||||
printf("Done.\n");
|
||||
dev->disk_loaded=1;
|
||||
dev->media_changed=1;
|
||||
dev->req_image_load=0;
|
||||
cdrom_error(dev,0x11); //media changed
|
||||
dev->disk_loaded = 1;
|
||||
dev->media_changed = 1;
|
||||
cdrom_error(dev, 0x11); //media changed
|
||||
}
|
||||
}
|
||||
else {
|
||||
cdrom_read_data(dev);
|
||||
dev->image_command = CD_COMMAND_NONE;
|
||||
dev->image_status = CD_STATUS_IDLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -651,6 +667,7 @@ void __inline cdrom_read_data(cdrom_t *dev) {
|
||||
TODO, need to handle when multiple blocks are requested.
|
||||
*/
|
||||
if(dev->req_total) {
|
||||
/* while(dev->req_total) { */
|
||||
if(cdrom_fifo_level(&dev->data_fifo) >= 2048) return;//need to be empty.
|
||||
pos = MSFtoLBA(dev->req_m,dev->req_s,dev->req_f) - 150;
|
||||
pos += dev->req_cur;
|
||||
|
||||
+23
-4
@@ -75,6 +75,23 @@ extern "C" {
|
||||
/* To shut up the GCC compilers. */
|
||||
struct cdrom;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CD_COMMAND_NONE,
|
||||
CD_COMMAND_IMAGE_LOAD,
|
||||
CD_COMMAND_IMAGE_LOAD_INDEX,
|
||||
CD_COMMAND_IMAGE_EJECT,
|
||||
CD_COMMAND_IMAGE_LIST
|
||||
} cdrom_image_command_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CD_STATUS_ERROR = -1,
|
||||
CD_STATUS_IDLE,
|
||||
CD_STATUS_BUSY,
|
||||
CD_STATUS_READY,
|
||||
} cdrom_image_status_t;
|
||||
|
||||
typedef struct subchannel_t {
|
||||
uint8_t attr;
|
||||
uint8_t track;
|
||||
@@ -134,10 +151,11 @@ typedef struct cdrom {
|
||||
|
||||
|
||||
uint8_t media_changed;
|
||||
uint8_t req_image_load;
|
||||
cdrom_image_command_t image_command;
|
||||
cdrom_image_status_t image_status;
|
||||
uint8_t image_data;
|
||||
uint8_t disk_loaded;
|
||||
|
||||
|
||||
uint8_t cd_status; /* Struct variable reserved for
|
||||
media status. */
|
||||
uint8_t speed;
|
||||
@@ -149,8 +167,9 @@ typedef struct cdrom {
|
||||
int is_dir;
|
||||
void *priv;
|
||||
|
||||
char image_path[1024];
|
||||
//char prev_image_path[1024];
|
||||
char **image_list;
|
||||
int image_count;
|
||||
char image_path[256];
|
||||
|
||||
uint32_t sound_on;
|
||||
uint32_t cdrom_capacity;
|
||||
|
||||
@@ -75,7 +75,7 @@ static inline void frames_to_msf(uint32_t total_frames, uint8_t *pM, uint8_t *pS
|
||||
#define MAX_FILENAME_LENGTH 256
|
||||
#define CROSS_LEN 512
|
||||
|
||||
static char temp_keyword[1024];
|
||||
static char temp_keyword[64];
|
||||
|
||||
#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG
|
||||
int cdrom_image_backend_do_log = ENABLE_CDROM_IMAGE_BACKEND_LOG;
|
||||
@@ -192,7 +192,7 @@ bin_init(const char *filename, int *error)
|
||||
|
||||
if (tf == NULL) {
|
||||
*error = 1;
|
||||
printf("can't malloc\n");
|
||||
cdrom_image_backend_log("can't malloc\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -202,9 +202,9 @@ bin_init(const char *filename, int *error)
|
||||
|
||||
tf->fp = (FIL *) malloc(sizeof(FIL));
|
||||
FRESULT result = f_open(tf->fp, tf->fn, FA_READ);
|
||||
printf("CDROM: binary_open(%s) = %08lx, result %d\n", tf->fn, tf->fp, result);
|
||||
cdrom_image_backend_log("CDROM: binary_open(%s) = %08lx, result %d\n", tf->fn, tf->fp, result);
|
||||
FSIZE_t len = f_size(tf->fp);
|
||||
printf("file size: %u", len);
|
||||
cdrom_image_backend_log("file size: %u", len);
|
||||
|
||||
/* if (f_stat(tf->fn, &stats) != 0) { */
|
||||
/* #<{(| Use a blank structure if stat failed. |)}># */
|
||||
@@ -215,7 +215,7 @@ bin_init(const char *filename, int *error)
|
||||
/* #<{(| Set the function pointers. |)}># */
|
||||
/* if (!*error) { */
|
||||
if (result == FR_OK) {
|
||||
printf("all good\n");
|
||||
cdrom_image_backend_log("all good\n");
|
||||
tf->read = bin_read;
|
||||
tf->get_length = bin_get_length;
|
||||
tf->close = bin_close;
|
||||
@@ -941,19 +941,19 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
|
||||
putchar('a');
|
||||
/* fp = (FIL *) malloc(sizeof(FIL)); */
|
||||
FRESULT result = f_open(&fp, cuefile, FA_READ);
|
||||
printf("result: %u\n", result);
|
||||
cdrom_image_backend_log("result: %u\n", result);
|
||||
if (result != FR_OK)
|
||||
return 0;
|
||||
|
||||
FSIZE_t len = f_size(&fp);
|
||||
printf("file size: %u", len);
|
||||
cdrom_image_backend_log("file size: %u", len);
|
||||
|
||||
success = 0;
|
||||
/* while (f_gets(buf, sizeof buf, &fp)) { */
|
||||
/* puts(buf); */
|
||||
/* } */
|
||||
/* int err = f_error(&fp); */
|
||||
/* printf("error: %u", err); */
|
||||
/* cdrom_image_backend_log("error: %u", err); */
|
||||
/* return 0; */
|
||||
for (;;) {
|
||||
line = buf;
|
||||
@@ -961,11 +961,11 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
|
||||
//if (feof(fp) || fgets(buf, sizeof(buf), fp) == NULL || ferror(fp))
|
||||
|
||||
if(f_eof(&fp)) {
|
||||
printf("eof\n");
|
||||
cdrom_image_backend_log("eof\n");
|
||||
break;
|
||||
}
|
||||
if (f_gets(buf, sizeof(buf), &fp) == NULL) {
|
||||
printf("no more read\n");
|
||||
cdrom_image_backend_log("no more read\n");
|
||||
break;
|
||||
}
|
||||
puts(buf);
|
||||
@@ -984,7 +984,7 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
|
||||
}
|
||||
|
||||
success = cdi_cue_get_keyword(&command, &line);
|
||||
printf("command: %s\n", command);
|
||||
cdrom_image_backend_log("command: %s\n", command);
|
||||
|
||||
if (!strcmp(command, "TRACK")) {
|
||||
if (can_add_track) {
|
||||
@@ -1132,7 +1132,7 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
|
||||
putchar('7');
|
||||
if (error) {
|
||||
/* #ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG */
|
||||
printf("CUE: cannot open fille '%s' in cue sheet!\n",
|
||||
cdrom_image_backend_log("CUE: cannot open fille '%s' in cue sheet!\n",
|
||||
filename);
|
||||
/* #endif */
|
||||
if (trk.file != NULL) {
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
#include "cdrom_image_manager.h"
|
||||
|
||||
#include "ff.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
// Maximum number of files to list
|
||||
#define MAX_FILES 100
|
||||
// Maximum filename length
|
||||
#define MAX_FILENAME_LEN 64
|
||||
|
||||
// Structure to hold filename and allow sorting
|
||||
typedef char FileEntry[MAX_FILENAME_LEN];
|
||||
|
||||
// Comparison function for qsort (case insensitive ASCIIbetical sorting)
|
||||
static int cmp(const void *a, const void *b) {
|
||||
const FileEntry *fileA = (const FileEntry *)a;
|
||||
const FileEntry *fileB = (const FileEntry *)b;
|
||||
return strncasecmp(*fileA, *fileB, MAX_FILENAME_LEN);
|
||||
}
|
||||
|
||||
// Function to check if filename has .iso or .cue extension
|
||||
static int isCDImage(const char *filename) {
|
||||
int len = strlen(filename);
|
||||
if (len < 4) return 0;
|
||||
// Filter out macOS extended attribute files
|
||||
if (strncmp(filename, "._", 2) == 0) {
|
||||
return 0;
|
||||
}
|
||||
return (strncasecmp(filename + (len - 4), ".iso", 4) == 0 ||
|
||||
strncasecmp(filename + (len -4), ".cue", 4) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists files in a directory with .iso and .cue extensions, sorted alphabetically
|
||||
*
|
||||
* @param fileCount: Pointer to int that will receive the number of files found
|
||||
* @return: Array of strings containing filenames, or NULL on error
|
||||
* Caller is responsible for freeing the memory
|
||||
*/
|
||||
char** cdman_list_images(int *fileCount) {
|
||||
if (!fileCount) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*fileCount = 0;
|
||||
|
||||
// Open the directory
|
||||
DIR dp;
|
||||
FRESULT res = f_opendir(&dp, "");
|
||||
if (res != FR_OK) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Array to store file entries for sorting
|
||||
FileEntry *entries = (FileEntry *)malloc(MAX_FILES * sizeof(FileEntry));
|
||||
if (!entries) {
|
||||
f_closedir(&dp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
FILINFO fno;
|
||||
|
||||
// Read directory entries
|
||||
while (count < MAX_FILES) {
|
||||
res = f_readdir(&dp, &fno);
|
||||
if (res != FR_OK || fno.fname[0] == 0) {
|
||||
break; // End of directory or error
|
||||
}
|
||||
|
||||
// Skip directories
|
||||
if (fno.fattrib & AM_DIR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if it has valid extension
|
||||
if (isCDImage(fno.fname)) {
|
||||
strncpy(entries[count], fno.fname, MAX_FILENAME_LEN - 1);
|
||||
entries[count][MAX_FILENAME_LEN - 1] = '\0';
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
f_closedir(&dp);
|
||||
|
||||
if (count == 0) {
|
||||
free(entries);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Sort the entries alphabetically
|
||||
qsort(entries, count, sizeof(FileEntry), cmp);
|
||||
|
||||
// Allocate array of string pointers
|
||||
char **fileList = (char **)malloc(count * sizeof(char *));
|
||||
if (!fileList) {
|
||||
free(entries);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Allocate memory for each filename string
|
||||
for (int i = 0; i < count; i++) {
|
||||
int len = strlen(entries[i]) + 1;
|
||||
fileList[i] = (char *)malloc(len);
|
||||
if (fileList[i]) {
|
||||
strcpy(fileList[i], entries[i]);
|
||||
printf("%s\n", fileList[i]);
|
||||
} else {
|
||||
// Clean up on allocation failure
|
||||
for (int j = 0; j < i; j++) {
|
||||
free(fileList[j]);
|
||||
}
|
||||
free(fileList);
|
||||
free(entries);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
free(entries);
|
||||
*fileCount = count;
|
||||
return fileList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to free the array returned by listBinCueFiles
|
||||
*
|
||||
* @param fileList: Array of strings returned by listBinCueFiles
|
||||
* @param fileCount: Number of files in the array
|
||||
*/
|
||||
void cdman_list_images_free(char **fileList, int fileCount) {
|
||||
if (fileList) {
|
||||
for (int i = 0; i < fileCount; i++) {
|
||||
if (fileList[i]) {
|
||||
free(fileList[i]);
|
||||
}
|
||||
}
|
||||
free(fileList);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t current_index;
|
||||
|
||||
uint8_t cdman_current_image_index(void) {
|
||||
return current_index;
|
||||
}
|
||||
|
||||
|
||||
void cdman_load_image_index(cdrom_t *dev, int imageIndex) {
|
||||
int imageCount;
|
||||
char** images = cdman_list_images(&imageCount);
|
||||
if (imageIndex > imageCount) {
|
||||
return;
|
||||
} else if (imageIndex == 0) {
|
||||
cdman_unload_image(dev);
|
||||
} else {
|
||||
cdman_load_image(dev, images[imageIndex - 1]);
|
||||
}
|
||||
cdman_list_images_free(images, imageCount);
|
||||
current_index = imageIndex;
|
||||
}
|
||||
|
||||
|
||||
void cdman_load_image(cdrom_t *dev, char *imageName) {
|
||||
strcpy(dev->image_path, imageName);
|
||||
dev->image_command = CD_COMMAND_IMAGE_LOAD;
|
||||
}
|
||||
|
||||
|
||||
void cdman_unload_image(cdrom_t *dev) {
|
||||
dev->image_path[0] = 0;
|
||||
dev->image_command = CD_COMMAND_IMAGE_LOAD;
|
||||
current_index = 0;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t drive_serial;
|
||||
|
||||
void cdman_set_serial(uint32_t serial) {
|
||||
if (drive_serial == serial) {
|
||||
// If we are re-inserting the same drive, maybe advance the disc image
|
||||
printf("Inserting the same drive...\n");
|
||||
} else {
|
||||
drive_serial = serial;
|
||||
printf("New drive with serial %u inserted", serial);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "cdrom.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
char** cdman_list_images(int *fileCount);
|
||||
void cdman_list_images_free(char **fileList, int fileCount);
|
||||
|
||||
uint8_t cdman_current_image_index(void);
|
||||
void cdman_load_image_index(cdrom_t *dev, int imageIndex);
|
||||
void cdman_load_image(cdrom_t *dev, char *imageName);
|
||||
void cdman_unload_image(cdrom_t *dev);
|
||||
void cdman_set_serial(uint32_t serial);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
+12
-5
@@ -32,6 +32,8 @@
|
||||
|
||||
#include "msc_app.h"
|
||||
|
||||
#include "cdrom_image_manager.h"
|
||||
extern cdrom_t cdrom[CDROM_NUM];
|
||||
|
||||
//------------- Elm Chan FatFS -------------//
|
||||
static FATFS fatfs[CFG_TUH_DEVICE_MAX]; // for simplicity only support 1 LUN per device
|
||||
@@ -89,19 +91,22 @@ static bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const
|
||||
if ( f_mount(&fatfs[drive_num], drive_path, 1) != FR_OK )
|
||||
{
|
||||
puts("mount failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
// change to newly mounted drive
|
||||
if (f_chdir(drive_path) != FR_OK) {
|
||||
puts("chdir failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
// print the drive label
|
||||
// char label[34];
|
||||
// if ( FR_OK == f_getlabel(drive_path, label, NULL) )
|
||||
// {
|
||||
// puts(label);
|
||||
// }
|
||||
uint32_t serial;
|
||||
if ( FR_OK != f_getlabel(drive_path, NULL, &serial) ) {
|
||||
return false;
|
||||
}
|
||||
cdman_set_serial(serial);
|
||||
/* cdman_load_image_index(&cdrom[0], 1); */
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -125,6 +130,8 @@ void tuh_msc_umount_cb(uint8_t dev_addr)
|
||||
|
||||
f_unmount(drive_path);
|
||||
|
||||
cdman_unload_image(&cdrom[0]);
|
||||
|
||||
// if ( phy_disk == f_get_current_drive() )
|
||||
// { // active drive is unplugged --> change to other drive
|
||||
// for(uint8_t i=0; i<CFG_TUH_DEVICE_MAX; i++)
|
||||
|
||||
@@ -69,6 +69,9 @@ static const Settings defaultSettings = {
|
||||
.WiFi = {
|
||||
.ssid = {0},
|
||||
.password = {0}
|
||||
},
|
||||
.CD = {
|
||||
.basePort = 0x230
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -73,6 +73,9 @@ typedef struct Settings {
|
||||
char ssid[33];
|
||||
char password[64];
|
||||
} WiFi;
|
||||
struct {
|
||||
uint16_t basePort;
|
||||
} CD;
|
||||
} Settings;
|
||||
|
||||
|
||||
|
||||
+39
-36
@@ -60,6 +60,7 @@ Data (input) = base + 2 (base)
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define mke_log(fmt, ...)
|
||||
|
||||
#define MKE_STATUS_FIFO_SIZE 256
|
||||
#define MKE_DATA_FIFO_SIZE 16
|
||||
@@ -95,7 +96,7 @@ void MKE_COMMAND(uint8_t value) {
|
||||
}
|
||||
|
||||
if(mke.command_buffer[0] == CMD1_ABORT) {
|
||||
printf("CMD_ABORT\n");
|
||||
mke_log("CMD_ABORT\n");
|
||||
cdrom_fifo_clear(&cdrom[0].info_fifo);
|
||||
mke.command_buffer[0]=0;
|
||||
mke.command_buffer_pending=7;
|
||||
@@ -106,13 +107,13 @@ void MKE_COMMAND(uint8_t value) {
|
||||
switch(mke.command_buffer[0]) {
|
||||
case 06: //TRAY OUT
|
||||
cdrom_fifo_clear(&cdrom[0].info_fifo);
|
||||
printf("TRAY OUT\n");
|
||||
mke_log("TRAY OUT\n");
|
||||
cdrom_output_status(&cdrom[0]);
|
||||
mke.tray_open=true;
|
||||
break;
|
||||
case 07: //TRAY IN
|
||||
cdrom_fifo_clear(&cdrom[0].info_fifo);
|
||||
printf("TRAY IN\n");
|
||||
mke_log("TRAY IN\n");
|
||||
cdrom_output_status(&cdrom[0]);
|
||||
mke.tray_open=false;
|
||||
break;
|
||||
@@ -137,15 +138,15 @@ void MKE_COMMAND(uint8_t value) {
|
||||
break;
|
||||
case CMD1_SETMODE: //Returns 1
|
||||
cdrom_fifo_clear(&cdrom[0].info_fifo);
|
||||
printf("CMD: SET MODE:");
|
||||
mke_log("CMD: SET MODE:");
|
||||
for(i=0;i<6;i++) {
|
||||
printf("%02x ",mke.command_buffer[i+1]);
|
||||
mke_log("%02x ",mke.command_buffer[i+1]);
|
||||
}
|
||||
printf("\n");
|
||||
mke_log("\n");
|
||||
cdrom_output_status(&cdrom[0]);
|
||||
break;
|
||||
case CMD1_GETMODE://6
|
||||
printf("GET MODE\n");
|
||||
mke_log("GET MODE\n");
|
||||
uint8_t mode[5] = {[1] = 0x08};
|
||||
cdrom_fifo_write_multiple(&cdrom[0].info_fifo, mode, 5);
|
||||
cdrom_output_status(&cdrom[0]);
|
||||
@@ -155,51 +156,51 @@ void MKE_COMMAND(uint8_t value) {
|
||||
cdrom_output_status(&cdrom[0]);
|
||||
break;
|
||||
case CMD1_CAPACITY://6
|
||||
printf("DISK CAPACITY\n");
|
||||
mke_log("DISK CAPACITY\n");
|
||||
cdrom_disc_capacity(&cdrom[0], (uint8_t *)&x);
|
||||
cdrom_fifo_write_multiple(&cdrom[0].info_fifo, x, 5);
|
||||
cdrom_output_status(&cdrom[0]);
|
||||
break;
|
||||
case CMD1_DISKINFO: //7
|
||||
printf("DISK INFO\n");
|
||||
mke_log("DISK INFO\n");
|
||||
cdrom_disc_info(&cdrom[0], (uint8_t *)&x);
|
||||
cdrom_fifo_write_multiple(&cdrom[0].info_fifo, x, 6);
|
||||
/*
|
||||
for(i=0;i<6;i++) {
|
||||
printf("%02x ",x[i]);
|
||||
mke_log("%02x ",x[i]);
|
||||
cdrom_fifo_write(&cdrom[0].info_fifo,x[i]);
|
||||
}
|
||||
printf("\n");
|
||||
mke_log("\n");
|
||||
*/
|
||||
cdrom_output_status(&cdrom[0]);
|
||||
break;
|
||||
case CMD1_READTOC:
|
||||
cdrom_fifo_clear(&cdrom[0].info_fifo);
|
||||
/*
|
||||
printf("READ TOC:");
|
||||
mke_log("READ TOC:");
|
||||
for(i=0;i<6;i++) {
|
||||
printf("%02x ",mke.command_buffer[i+1]);
|
||||
mke_log("%02x ",mke.command_buffer[i+1]);
|
||||
}
|
||||
printf(" | ");
|
||||
mke_log(" | ");
|
||||
*/
|
||||
cdrom_read_toc(&cdrom[0],(uint8_t *)&x,mke.command_buffer[2]);
|
||||
cdrom_fifo_write_multiple(&cdrom[0].info_fifo, x, 8);
|
||||
/*
|
||||
for(i=0;i<8;i++) {
|
||||
printf("%02x ",x[i]);
|
||||
mke_log("%02x ",x[i]);
|
||||
cdrom_fifo_write(&cdrom[0].info_fifo,x[i]);
|
||||
}
|
||||
*/
|
||||
/* printf("\n"); */
|
||||
/* mke_log("\n"); */
|
||||
cdrom_output_status(&cdrom[0]);
|
||||
break;
|
||||
case CMD1_PLAY_MSF:
|
||||
cdrom_fifo_clear(&cdrom[0].info_fifo);
|
||||
printf("PLAY MSF:");
|
||||
mke_log("PLAY MSF:");
|
||||
for(i=0;i<6;i++) {
|
||||
printf("%02x ",mke.command_buffer[i+1]);
|
||||
mke_log("%02x ",mke.command_buffer[i+1]);
|
||||
}
|
||||
printf("\n");
|
||||
mke_log("\n");
|
||||
cdrom_audio_playmsf(&cdrom[0],
|
||||
mke.command_buffer[1],
|
||||
mke.command_buffer[2],
|
||||
@@ -212,30 +213,30 @@ void MKE_COMMAND(uint8_t value) {
|
||||
break;
|
||||
case CMD1_SEEK :
|
||||
cdrom_fifo_clear(&cdrom[0].info_fifo);
|
||||
printf("SEEK MSF:"); //TODO: DOES THIS IMPACT CURRENT PLAY LENGTH?
|
||||
mke_log("SEEK MSF:"); //TODO: DOES THIS IMPACT CURRENT PLAY LENGTH?
|
||||
for(i=0;i<6;i++) {
|
||||
printf("%02x ",mke.command_buffer[i+1]);
|
||||
mke_log("%02x ",mke.command_buffer[i+1]);
|
||||
}
|
||||
cdrom_seek(&cdrom[0],mke.command_buffer[1],mke.command_buffer[2],mke.command_buffer[3]);
|
||||
cdrom_output_status(&cdrom[0]);
|
||||
break;
|
||||
case CMD1_SESSINFO:
|
||||
cdrom_fifo_clear(&cdrom[0].info_fifo);
|
||||
printf("CMD: READ SESSION INFO\n");
|
||||
mke_log("CMD: READ SESSION INFO\n");
|
||||
uint8_t session_info[6] = {0};
|
||||
cdrom_fifo_write_multiple(&cdrom[0].info_fifo, session_info, 6);
|
||||
cdrom_output_status(&cdrom[0]);
|
||||
break;
|
||||
case CMD1_READ_UPC:
|
||||
cdrom_fifo_clear(&cdrom[0].info_fifo);
|
||||
printf("CMD: READ UPC\n");
|
||||
mke_log("CMD: READ UPC\n");
|
||||
uint8_t upc[8] = {[0] = 80};
|
||||
cdrom_fifo_write_multiple(&cdrom[0].info_fifo, upc, 8);
|
||||
cdrom_output_status(&cdrom[0]);
|
||||
break;
|
||||
case CMD1_READ_ERR:
|
||||
cdrom_fifo_clear(&cdrom[0].info_fifo);
|
||||
printf("CMD: READ ERR\n");
|
||||
mke_log("CMD: READ ERR\n");
|
||||
cdrom_read_errors(&cdrom[0],(uint8_t *)x);
|
||||
cdrom_fifo_write_multiple(&cdrom[0].info_fifo, x, 8);
|
||||
cdrom_output_status(&cdrom[0]);
|
||||
@@ -245,7 +246,7 @@ void MKE_COMMAND(uint8_t value) {
|
||||
SB2CD Expects 12 bytes, but drive only returns 11.
|
||||
*/
|
||||
cdrom_fifo_clear(&cdrom[0].info_fifo);
|
||||
printf("CMD: READ VER\n");
|
||||
mke_log("CMD: READ VER\n");
|
||||
uint8_t ver[10] = "CR-5630.75";
|
||||
cdrom_fifo_write_multiple(&cdrom[0].info_fifo, ver, 10);
|
||||
cdrom_output_status(&cdrom[0]);
|
||||
@@ -255,7 +256,7 @@ void MKE_COMMAND(uint8_t value) {
|
||||
cdrom_output_status(&cdrom[0]);
|
||||
break;
|
||||
default:
|
||||
printf("MKE: Unknown Commnad [%02x]\n",mke.command_buffer[0]);
|
||||
mke_log("MKE: Unknown Commnad [%02x]\n",mke.command_buffer[0]);
|
||||
}
|
||||
mke.command_buffer[0]=0;
|
||||
}
|
||||
@@ -268,10 +269,10 @@ void MKE_COMMAND(uint8_t value) {
|
||||
|
||||
void MKE_WRITE(uint16_t address, uint8_t value) {
|
||||
if(mke.enable_register && ((address & 0xF) != 3)) {
|
||||
//printf("Ignore Write Unit %u\n",mke.enable_register);
|
||||
//mke_log("Ignore Write Unit %u\n",mke.enable_register);
|
||||
return;
|
||||
}
|
||||
//printf("MKE WRITE: %02x => %03x\n",value,address);
|
||||
//mke_log("MKE WRITE: %02x => %03x\n",value,address);
|
||||
switch(address & 0xF) {
|
||||
case 0:
|
||||
MKE_COMMAND(value);
|
||||
@@ -279,36 +280,37 @@ void MKE_WRITE(uint16_t address, uint8_t value) {
|
||||
case 1:
|
||||
mke.data_select=value;
|
||||
break;
|
||||
/*
|
||||
case 2:
|
||||
switch(value) {
|
||||
case 1:
|
||||
sprintf(cdrom[0].image_path,"MECH2_16B.CUE");
|
||||
break;
|
||||
case 2:
|
||||
sprintf(cdrom[0].image_path,"MOC1.cue");
|
||||
sprintf(cdrom[0].image_path,"descent-ii.cue");
|
||||
break;
|
||||
/*
|
||||
case 3:
|
||||
sprintf(cdrom[0].image_path,"war2.cue");
|
||||
sprintf(cdrom[0].image_path,"Loom (USA).cue");
|
||||
break;
|
||||
case 4:
|
||||
sprintf(cdrom[0].image_path,"myst.iso");
|
||||
sprintf(cdrom[0].image_path,"MYST.cue");
|
||||
break;
|
||||
case 5:
|
||||
sprintf(cdrom[0].image_path,"megarace.iso");
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
sprintf(cdrom[0].image_path,"");
|
||||
break;
|
||||
}
|
||||
cdrom[0].req_image_load=1;
|
||||
cdrom[0].req_command = CD_COMMAND_IMAGE_LOAD;
|
||||
printf("loaded %s\n", cdrom[0].image_path);
|
||||
break;
|
||||
*/
|
||||
case 3:
|
||||
mke.enable_register=value;
|
||||
break;
|
||||
default:
|
||||
printf("w %03x %02x\n", address, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -349,6 +351,7 @@ uint8_t MKE_READ(uint16_t address) {
|
||||
return mke.enable_register;
|
||||
break;
|
||||
default:
|
||||
/* mke_log("MKE Unknown Read Address: %03x\n",address); */
|
||||
printf("MKE Unknown Read Address: %03x\n",address);
|
||||
break;
|
||||
}
|
||||
@@ -357,11 +360,11 @@ uint8_t MKE_READ(uint16_t address) {
|
||||
|
||||
|
||||
|
||||
void mke_init() {
|
||||
void mke_init() {
|
||||
cdrom_fifo_init(&cdrom[0].data_fifo,2048+2048+32);
|
||||
cdrom_fifo_init(&cdrom[0].info_fifo,32);
|
||||
cdrom_audio_fifo_init(&cdrom[0]);
|
||||
printf("FIFOS, INFO=%p DATA=%p\n",cdrom[0].info_fifo,cdrom[0].data_fifo);
|
||||
mke_log("FIFOS, INFO=%p DATA=%p\n",cdrom[0].info_fifo,cdrom[0].data_fifo);
|
||||
|
||||
mke.command_buffer_pending=7;
|
||||
cdrom[0].sound_on=1;
|
||||
|
||||
+87
-13
@@ -75,13 +75,17 @@ cms_buffer_t opl_buffer = { {0}, 0, 0 };
|
||||
#endif
|
||||
|
||||
#ifdef CDROM
|
||||
static uint16_t cdrom_port_test;
|
||||
extern "C" void MKE_WRITE(uint16_t address, uint8_t value);
|
||||
extern "C" uint8_t MKE_READ(uint16_t address);
|
||||
extern "C" void mke_init();
|
||||
|
||||
#define CDROM_NUM 1
|
||||
#include "cdrom/cdrom.h"
|
||||
#include "cdrom/cdrom_image_manager.h"
|
||||
cdrom_t cdrom[CDROM_NUM];
|
||||
|
||||
static uint32_t cur_read_idx;
|
||||
#endif
|
||||
|
||||
#ifdef SOUND_GUS
|
||||
@@ -214,6 +218,26 @@ __force_inline void select_picogus(uint8_t value) {
|
||||
case MODE_WIFIAPPLY:
|
||||
case MODE_WIFISTAT:
|
||||
break;
|
||||
case MODE_CDPORT: // CMS Base port
|
||||
basePort_low = 0;
|
||||
break;
|
||||
case MODE_CDSTATUS:
|
||||
break;
|
||||
case MODE_CDIMAGES:
|
||||
#ifdef CDROM
|
||||
if (cdrom[0].image_status != CD_STATUS_READY) {
|
||||
cdrom[0].image_status = CD_STATUS_BUSY;
|
||||
cdrom[0].image_command = CD_COMMAND_IMAGE_LIST;
|
||||
puts("cdimages start");
|
||||
}
|
||||
puts("cdimages read");
|
||||
cur_read = 0;
|
||||
cur_read_idx = 0;
|
||||
#endif
|
||||
break;
|
||||
case MODE_CDLOAD:
|
||||
case MODE_CDSELECT:
|
||||
break;
|
||||
case MODE_SAVE: // Select save settings register
|
||||
case MODE_REBOOT: // Select reboot register
|
||||
case MODE_DEFAULTS: // Select reset to defaults register
|
||||
@@ -238,6 +262,7 @@ __force_inline void write_picogus_low(uint8_t value) {
|
||||
case MODE_TANDYPORT: // Tandy Base port
|
||||
case MODE_CMSPORT: // CMS Base port
|
||||
case MODE_MOUSEPORT: // USB Mouse port (0 - disabled)
|
||||
case MODE_CDPORT: // USB Mouse port (0 - disabled)
|
||||
basePort_low = value;
|
||||
break;
|
||||
case MODE_MOUSESEN: // USB Mouse Sensitivity (8.8 fixedpoint)
|
||||
@@ -357,6 +382,21 @@ __force_inline void write_picogus_high(uint8_t value) {
|
||||
multicore_fifo_push_blocking(FIFO_WIFI_STATUS);
|
||||
#endif
|
||||
break;
|
||||
case MODE_CDPORT: // CD Base port
|
||||
settings.CD.basePort = (value || basePort_low) ? ((value << 8) | basePort_low) : 0xFFFF;
|
||||
#ifdef CDROM
|
||||
cdrom_port_test = settings.CD.basePort >> 4;
|
||||
#endif
|
||||
break;
|
||||
#ifdef CDROM
|
||||
case MODE_CDLOAD: // Load CD image
|
||||
cdrom[0].image_data = value;
|
||||
cdrom[0].image_status = CD_STATUS_BUSY;
|
||||
cdrom[0].image_command = CD_COMMAND_IMAGE_LOAD_INDEX;
|
||||
break;
|
||||
case MODE_CDSELECT:
|
||||
break;
|
||||
#endif
|
||||
// For multifw
|
||||
case MODE_BOOTMODE:
|
||||
settings.startupMode = value;
|
||||
@@ -400,6 +440,8 @@ __force_inline uint8_t read_picogus_low(void) {
|
||||
return settings.Mouse.sensitivity & 0xFF;
|
||||
case MODE_NE2KPORT: // NE2000 Base port (0 - disabled)
|
||||
return settings.NE2K.basePort == 0xFFFF ? 0 : (settings.NE2K.basePort & 0xFF);
|
||||
case MODE_CDPORT: // SB Base port
|
||||
return settings.CD.basePort == 0xFFFF ? 0 : (settings.CD.basePort & 0xFF);
|
||||
default:
|
||||
return 0x0;
|
||||
}
|
||||
@@ -471,6 +513,29 @@ __force_inline uint8_t read_picogus_high(void) {
|
||||
return 0;
|
||||
#endif
|
||||
break;
|
||||
case MODE_CDPORT: // SB Base port
|
||||
return settings.CD.basePort == 0xFFFF ? 0 : (settings.CD.basePort >> 8);
|
||||
#ifdef CDROM
|
||||
case MODE_CDSTATUS:
|
||||
printf("cdstatus %x\n", cdrom[0].image_status);
|
||||
return cdrom[0].image_status;
|
||||
case MODE_CDIMAGES:
|
||||
if (cur_read_idx == cdrom[0].image_count) { // If end of the images
|
||||
cur_read_idx = cur_read = 0;
|
||||
cdrom[0].image_status = CD_STATUS_IDLE;
|
||||
cdman_list_images_free(cdrom[0].image_list, cdrom[0].image_count);
|
||||
return 0x04; // EOT
|
||||
}
|
||||
ret = cdrom[0].image_list[cur_read_idx][cur_read++];
|
||||
putchar(ret);
|
||||
if (ret == 0) { // Null terminated
|
||||
++cur_read_idx;
|
||||
cur_read = 0;
|
||||
}
|
||||
return ret;
|
||||
case MODE_CDLOAD: // Load CD image
|
||||
return cdman_current_image_index();
|
||||
#endif
|
||||
case MODE_HWTYPE: // Hardware version
|
||||
return BOARD_TYPE;
|
||||
case MODE_FLASH:
|
||||
@@ -503,7 +568,7 @@ void processSettings(void) {
|
||||
settings.startupMode = INVALID_MODE;
|
||||
#endif
|
||||
#ifdef SOUND_SB
|
||||
sb_port_test = settings.SB.basePort >> 5;
|
||||
sb_port_test = settings.SB.basePort >> 4;
|
||||
#endif
|
||||
#ifdef SOUND_GUS
|
||||
gus_port_test = settings.GUS.basePort >> 4 | 0x10;
|
||||
@@ -515,6 +580,10 @@ void processSettings(void) {
|
||||
sermouse_set_protocol(settings.Mouse.protocol);
|
||||
sermouse_set_report_rate_hz(settings.Mouse.reportRate);
|
||||
sermouse_set_sensitivity(settings.Mouse.sensitivity);
|
||||
#endif
|
||||
#ifdef CDROM
|
||||
cdrom_port_test = settings.CD.basePort >> 4;
|
||||
printf("cdrom base port: %x\n", settings.CD.basePort);
|
||||
#endif
|
||||
if (BOARD_TYPE == PICOGUS_2) {
|
||||
m62429->setVolume(M62429_BOTH, settings.Global.waveTableVolume);
|
||||
@@ -560,7 +629,7 @@ __force_inline void handle_iow(void) {
|
||||
} else // if follows down below
|
||||
#endif // SOUND_GUS
|
||||
#ifdef SOUND_SB
|
||||
if ((port >> 5) == sb_port_test) {
|
||||
if ((port >> 4) == sb_port_test) {
|
||||
switch (port - settings.SB.basePort) {
|
||||
// OPL ports
|
||||
case 0x8:
|
||||
@@ -581,11 +650,6 @@ __force_inline void handle_iow(void) {
|
||||
};
|
||||
break;
|
||||
// DSP ports
|
||||
case 0x10 ... 0x13:
|
||||
pio_sm_put(pio0, IOW_PIO_SM, IO_WAIT);
|
||||
// putchar('w');
|
||||
MKE_WRITE(port, iow_read & 0xFF);
|
||||
break;
|
||||
default:
|
||||
pio_sm_put(pio0, IOW_PIO_SM, IO_WAIT);
|
||||
sbdsp_process();
|
||||
@@ -595,6 +659,13 @@ __force_inline void handle_iow(void) {
|
||||
}
|
||||
} else // if follows down below
|
||||
#endif // SOUND_SB
|
||||
#ifdef CDROM
|
||||
if ((port >> 4) == cdrom_port_test) {
|
||||
pio_sm_put(pio0, IOW_PIO_SM, IO_WAIT);
|
||||
// putchar('w');
|
||||
MKE_WRITE(port, iow_read & 0xFF);
|
||||
} else // if follows down below
|
||||
#endif
|
||||
#if defined(SOUND_OPL)
|
||||
if (port == settings.SB.oplBasePort) {
|
||||
// Fast write
|
||||
@@ -745,7 +816,7 @@ __force_inline void handle_ior(void) {
|
||||
} else // if follows down below
|
||||
#endif
|
||||
#if defined(SOUND_SB)
|
||||
if ((port >> 5) == sb_port_test) {
|
||||
if ((port >> 4) == sb_port_test) {
|
||||
pio_sm_put(pio0, IOR_PIO_SM, IO_WAIT);
|
||||
switch (port - settings.SB.basePort) {
|
||||
case 0x8:
|
||||
@@ -755,11 +826,6 @@ __force_inline void handle_ior(void) {
|
||||
}
|
||||
pio_sm_put(pio0, IOR_PIO_SM, IOR_SET_VALUE | OPL_Pico_PortRead(OPL_REGISTER_PORT));
|
||||
break;
|
||||
case 0x10 ... 0x13:
|
||||
pio_sm_put(pio0, IOW_PIO_SM, IO_WAIT);
|
||||
// putchar('r');
|
||||
pio_sm_put(pio0, IOR_PIO_SM, IOR_SET_VALUE | MKE_READ(port));
|
||||
break;
|
||||
default:
|
||||
sbdsp_process();
|
||||
pio_sm_put(pio0, IOR_PIO_SM, IOR_SET_VALUE | sbdsp_read(port & 0xF));
|
||||
@@ -768,6 +834,14 @@ __force_inline void handle_ior(void) {
|
||||
}
|
||||
} else // if follows down below
|
||||
#endif
|
||||
#if defined(CDROM)
|
||||
if ((port >> 4) == cdrom_port_test) {
|
||||
// if ((port >> 4) == 0x23) {
|
||||
pio_sm_put(pio0, IOR_PIO_SM, IO_WAIT);
|
||||
pio_sm_put(pio0, IOR_PIO_SM, IOR_SET_VALUE | MKE_READ(port));
|
||||
// putchar('r');
|
||||
} else // if follows down below
|
||||
#endif
|
||||
#if defined(SOUND_OPL)
|
||||
if (port == settings.SB.oplBasePort) {
|
||||
// Tell PIO to wait for data
|
||||
|
||||
+36
-7
@@ -150,22 +150,47 @@ bool __force_inline sbdsp_fifo_half() {
|
||||
*/
|
||||
static int16_t __force_inline dma_interval_trim() {
|
||||
uint32_t level = fifo_level(&sbdsp.audio_fifo);
|
||||
if (level >= (AUDIO_FIFO_SIZE >> 1)) {
|
||||
// if (level >= (AUDIO_FIFO_SIZE >> 1)) {
|
||||
/*
|
||||
if (level >= 768) {
|
||||
// putchar('+');
|
||||
return 0;
|
||||
return sbdsp.dma_interval_trim;
|
||||
// return sbdsp.dma_interval_trim;
|
||||
} else {
|
||||
// putchar('-');
|
||||
return -sbdsp.dma_interval_trim;
|
||||
}
|
||||
// return (int32_t)(level >> 6) - 12;
|
||||
*/
|
||||
// return (int32_t)(level >> 4) - 32;
|
||||
// if(sbdsp_fifo_level() >= (DSP_DMA_FIFO_SIZE/2)) return true;
|
||||
// return false;
|
||||
}
|
||||
static int16_t __force_inline dma_interval_calc() {
|
||||
uint32_t level = fifo_level(&sbdsp.audio_fifo);
|
||||
if (level < 512) {
|
||||
return sbdsp.dma_interval - 5;
|
||||
} else {
|
||||
return sbdsp.dma_interval + 5;
|
||||
}
|
||||
// if (level >= (AUDIO_FIFO_SIZE >> 1)) {
|
||||
/*
|
||||
if (level >= 768) {
|
||||
// putchar('+');
|
||||
return sbdsp.dma_interval_trim;
|
||||
// return sbdsp.dma_interval_trim;
|
||||
} else {
|
||||
// putchar('-');
|
||||
return -sbdsp.dma_interval_trim;
|
||||
}
|
||||
*/
|
||||
// return (int32_t)(level >> 4) - 32;
|
||||
// if(sbdsp_fifo_level() >= (DSP_DMA_FIFO_SIZE/2)) return true;
|
||||
// return false;
|
||||
}
|
||||
|
||||
void __force_inline sbdsp_fifo_rx(uint8_t byte) {
|
||||
if (!fifo_add_sample(&sbdsp.audio_fifo, (int16_t)(byte ^ 0x80) << 8)) {
|
||||
// putchar('O');
|
||||
putchar('O');
|
||||
// printf("%d", dma_interval_trim());
|
||||
// printf("OVERRUN");
|
||||
}
|
||||
@@ -177,6 +202,7 @@ void __force_inline sbdsp_fifo_rx(uint8_t byte) {
|
||||
*/
|
||||
}
|
||||
void __force_inline sbdsp_fifo_clear() {
|
||||
fifo_set_state(&sbdsp.audio_fifo, FIFO_STATE_STOPPED);
|
||||
fifo_reset(&sbdsp.audio_fifo);
|
||||
// sbdsp.dma_buffer_head=sbdsp.dma_buffer_tail;
|
||||
}
|
||||
@@ -271,7 +297,7 @@ static __force_inline void sbdsp_dma_disable() {
|
||||
|
||||
static __force_inline void sbdsp_dma_enable() {
|
||||
if(!sbdsp.dma_enabled) {
|
||||
sbdsp_fifo_clear();
|
||||
// sbdsp_fifo_clear();
|
||||
sbdsp.dma_enabled=true;
|
||||
PIC_AddEvent(&DSP_DMA_Event, sbdsp.dma_interval, 0);
|
||||
fifo_set_state(&sbdsp.audio_fifo, FIFO_STATE_RUNNING);
|
||||
@@ -286,7 +312,8 @@ static uint32_t DSP_DMA_EventHandler(Bitu val) {
|
||||
uint32_t current_interval;
|
||||
sbdsp.dma_sample_count_rx++;
|
||||
|
||||
current_interval = sbdsp.dma_interval + dma_interval_trim();
|
||||
// current_interval = sbdsp.dma_interval + dma_interval_trim();
|
||||
current_interval = dma_interval_calc();
|
||||
// printf("%u\n", current_interval);
|
||||
|
||||
if(sbdsp.dma_sample_count_rx <= sbdsp.dma_sample_count) {
|
||||
@@ -404,7 +431,8 @@ void sbdsp_process(void) {
|
||||
*/
|
||||
sbdsp.dma_interval = 256 - sbdsp.time_constant;
|
||||
sbdsp.sample_rate = 1000000ul / sbdsp.dma_interval;
|
||||
sbdsp.dma_interval_trim = MAX(1, sbdsp.dma_interval >> 3);
|
||||
// sbdsp.dma_interval_trim = MAX(1, sbdsp.dma_interval >> 3);
|
||||
sbdsp.dma_interval_trim = MAX(1, sbdsp.dma_interval >> 1);
|
||||
// printf("interval: %u rate: %u, trim: %u\n", sbdsp.dma_interval, sbdsp.sample_rate, sbdsp.dma_interval_trim);
|
||||
// sbdsp.sample_step = sbdsp.sample_rate * 65535ul / OUTPUT_SAMPLERATE;
|
||||
// sbdsp.sample_factor = (OUTPUT_SAMPLERATE / sbdsp.sample_rate)+5; //Estimate
|
||||
@@ -597,6 +625,7 @@ static __force_inline void sbdsp_reset(uint8_t value) {
|
||||
PIC_RemoveEvent(&DSP_Reset_Event);
|
||||
sbdsp.autoinit=0;
|
||||
sbdsp_dma_disable();
|
||||
sbdsp_fifo_clear();
|
||||
sbdsp.reset_state=1;
|
||||
break;
|
||||
case 0:
|
||||
|
||||
+5
-3
@@ -166,9 +166,10 @@ void play_adlib() {
|
||||
struct audio_buffer_pool *ap = init_audio();
|
||||
|
||||
// uint8_t sb_samples[512] = {128};
|
||||
//
|
||||
audio_fifo_t* sb_fifo = sbdsp_fifo_peek();
|
||||
#ifdef CDROM
|
||||
audio_fifo_t* cd_fifo = cdrom_audio_fifo_peek(&cdrom[0]);
|
||||
#endif
|
||||
|
||||
// int16_t sb_sample = 0;
|
||||
uint32_t sb_ratio = 0;
|
||||
@@ -205,7 +206,7 @@ void play_adlib() {
|
||||
int32_t accum[2] = {0};
|
||||
for (int i = 0; i < SAMPLES_PER_BUFFER; ++i) {
|
||||
accum[0] = accum[1] = 0;
|
||||
|
||||
#ifdef CDROM
|
||||
if (!cd_left) {
|
||||
// if (cdrom_audio_callback_old(&cdrom[0], cd_samples, 1024)) {
|
||||
if (cdrom_audio_callback(&cdrom[0], AUDIO_FIFO_SIZE) && fifo_take_samples(cd_fifo, AUDIO_FIFO_SIZE)) {
|
||||
@@ -221,6 +222,7 @@ void play_adlib() {
|
||||
cd_index = (cd_index + 2) & AUDIO_FIFO_BITS;
|
||||
cd_left -= 2;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
uint32_t opl_index = (opl_pos >> FRAC_BITS);
|
||||
// uint32_t opl_index = i;
|
||||
@@ -284,7 +286,7 @@ void play_adlib() {
|
||||
sb_state = tmp_state;
|
||||
} else {
|
||||
if (sb_state == FIFO_STATE_RUNNING) {
|
||||
// putchar('U');
|
||||
putchar('U');
|
||||
}
|
||||
// printf("%u\n", sb_fifo->samples_in_fifo);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user