CD image handling

This commit is contained in:
Ian Scott committed 2025-06-12 23:10:52 -06:00
1 parent dd43203219
commit a7484c5b04
18 files changed
+589 -156

No files matched your search

+1 -1
View File
@@ -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
+11
View File
@@ -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
View File
@@ -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
-8
View File
@@ -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
View File
@@ -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);
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+12 -12
View File
@@ -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) {
+190
View File
@@ -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);
}
}
+20
View File
@@ -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
View File
@@ -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++)
+3
View File
@@ -69,6 +69,9 @@ static const Settings defaultSettings = {
.WiFi = {
.ssid = {0},
.password = {0}
},
.CD = {
.basePort = 0x230
}
};
+3
View File
@@ -73,6 +73,9 @@ typedef struct Settings {
char ssid[33];
char password[64];
} WiFi;
struct {
uint16_t basePort;
} CD;
} Settings;
+39 -36
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}