Simplify: single cdrom and fatfs instance, better support single USB drive

This commit is contained in:
Ian Scott committed 2025-06-15 11:40:21 -06:00
1 parent 20a0ecfb1a
commit 771f8f8948
11 files changed
+235 -1439

No files matched your search

+1 -1
View File
@@ -323,7 +323,7 @@ endfunction()
function(build_usb TARGET_NAME MULTIFW)
set(USB_JOYSTICK TRUE)
set(USB_MOUSE TRUE)
set(SOUND_MPU TRUE)
set(SOUND_MPU FALSE)
set(CDROM TRUE)
config_target(${TARGET_NAME} ${MULTIFW})
pico_set_program_name(${TARGET_NAME} "picogus-usb")
+14 -1137
View File
File diff suppressed because it is too large. Load diff
+10 -28
View File
@@ -24,8 +24,6 @@
#include <stdbool.h>
#include <stddef.h>
#define CDROM_NUM 1
#define CD_STATUS_EMPTY 0
#define CD_STATUS_DATA_ONLY 1
#define CD_STATUS_PAUSED 2
@@ -133,7 +131,9 @@ typedef struct cdrom_fifo_t {
} cdrom_fifo_t;
#if USE_CD_AUDIO_FIFO
#include "../audio_fifo.h"
#endif
typedef struct cdrom {
uint8_t id;
@@ -194,13 +194,15 @@ typedef struct cdrom {
// int16_t cd_buffer[BUF_SIZE];
uint8_t audio_sector_buffer[RAW_SECTOR_SIZE];
audio_sample_t *current_sector_samples; // Convenience pointer: (audio_sample_t*)audio_sector_buffer
int audio_sector_total_samples; // Samples available in current_sector_samples after a read
int audio_sector_consumed_samples; // Samples consumed from current_sector_samples
int16_t *current_sector_samples; // Convenience pointer: (int16_t*)audio_sector_buffer
int audio_sector_total_samples; // Samples available in current_sector_samples after a read
int audio_sector_consumed_samples; // Samples consumed from current_sector_samples
#if USE_CD_AUDIO_FIFO
audio_fifo_t audio_fifo;
#endif
} cdrom_t;
extern cdrom_t cdrom[CDROM_NUM];
extern cdrom_t cdrom;
extern void cdrom_error(cdrom_t *dev,uint8_t code);
extern void cdrom_read_errors(cdrom_t *dev,uint8_t *b);
@@ -219,8 +221,10 @@ void cdrom_tasks(cdrom_t *dev);
void cdrom_output_status(cdrom_t *dev);
uint8_t cdrom_status(cdrom_t *dev);
#if USE_CD_AUDIO_FIFO
extern audio_fifo_t* cdrom_audio_fifo_peek(cdrom_t *dev);
void cdrom_audio_fifo_init(cdrom_t *dev);
#endif
extern int cdrom_lba_to_msf_accurate(int lba);
extern double cdrom_seek_time(cdrom_t *dev);
@@ -228,21 +232,12 @@ extern void cdrom_stop(cdrom_t *dev);
extern int cdrom_is_pre(cdrom_t *dev, uint32_t lba);
extern bool cdrom_audio_callback(cdrom_t *dev, uint32_t len);
extern uint32_t cdrom_audio_callback_simple(cdrom_t *dev, int16_t *buffer, uint32_t len, bool pad);
// extern int cdrom_audio_callback_old(cdrom_t *dev, int16_t *output, int len);
// extern int cdrom_audio_callback_add(cdrom_t *dev, int16_t *output, int len);
extern uint8_t cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit);
extern uint8_t cdrom_audio_track_search_pioneer(cdrom_t *dev, uint32_t pos, uint8_t playbit);
extern uint8_t cdrom_audio_play_pioneer(cdrom_t *dev, uint32_t pos);
extern uint8_t cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type);
extern void cdrom_audio_pause_resume(cdrom_t *dev, uint8_t resume);
extern uint8_t cdrom_audio_scan(cdrom_t *dev, uint32_t pos, int type);
extern uint8_t cdrom_get_audio_status_pioneer(cdrom_t *dev, uint8_t *b);
extern uint8_t cdrom_get_audio_status_sony(cdrom_t *dev, uint8_t *b, int msf);
extern uint8_t cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf);
extern void cdrom_get_current_subchannel_sony(cdrom_t *dev, uint8_t *b, int msf);
extern void cdrom_get_current_subcodeq(cdrom_t *dev, uint8_t *b);
extern uint8_t cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b);
//Kevin
extern uint8_t cdrom_read_toc(cdrom_t *dev, unsigned char *b, uint8_t track);
@@ -252,16 +247,6 @@ extern uint8_t cdrom_seek(cdrom_t *dev, int m, int s, int f);
extern uint8_t cdrom_audio_playmsf(cdrom_t *dev, int m,int s, int f, int M, int S, int F);
extern uint8_t cdrom_get_subq(cdrom_t *dev,uint8_t *b);
extern void cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf);
extern void cdrom_get_q(cdrom_t *dev, uint8_t *buf, int *curtoctrk, uint8_t mode);
extern uint8_t cdrom_mitsumi_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len);
extern int cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf,
int cdrom_sector_type, int cdrom_sector_flags, int *len, uint8_t vendor_type);
extern void cdrom_debug(cdrom_t *dev);
extern void cdrom_close_handler(uint8_t id);
extern void cdrom_insert(uint8_t id);
extern void cdrom_eject(uint8_t id);
@@ -282,9 +267,6 @@ extern int find_cdrom_for_scsi_id(uint8_t scsi_id);
extern void cdrom_close(void);
extern void cdrom_global_init(void);
extern void cdrom_global_reset(void);
extern void cdrom_hard_reset(void);
extern void scsi_cdrom_drive_reset(int c);
#ifdef __cplusplus
}
+6 -10
View File
@@ -142,7 +142,7 @@ void cdman_list_images_free(char **fileList, int fileCount) {
}
}
static uint8_t current_index;
static uint8_t current_index, last_loaded_index;
uint8_t cdman_current_image_index(void) {
return current_index;
@@ -160,22 +160,18 @@ void cdman_load_image_index(cdrom_t *dev, int imageIndex) {
// Wrap around index for autoadvance
imageIndex = 1;
}
cdman_load_image(dev, images[imageIndex - 1]);
strcpy(dev->image_path, images[imageIndex - 1]);
dev->image_command = CD_COMMAND_IMAGE_LOAD;
}
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;
current_index = last_loaded_index = imageIndex;
}
void cdman_unload_image(cdrom_t *dev) {
dev->image_path[0] = 0;
dev->image_command = CD_COMMAND_IMAGE_LOAD;
current_index = 0;
}
@@ -191,7 +187,7 @@ void cdman_set_serial(cdrom_t *dev, 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");
cdman_load_image_index(dev, autoadvance ? (current_index + 1) : current_index);
cdman_load_image_index(dev, autoadvance ? (last_loaded_index + 1) : last_loaded_index);
} else {
drive_serial = serial;
printf("New drive with serial %u inserted", serial);
-1
View File
@@ -11,7 +11,6 @@ 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(cdrom_t *dev, uint32_t serial);
void cdman_set_autoadvance(bool setting);
+75 -119
View File
@@ -33,11 +33,11 @@
#include "msc_app.h"
#include "cdrom_image_manager.h"
extern cdrom_t cdrom[CDROM_NUM];
//------------- Elm Chan FatFS -------------//
static FATFS fatfs[CDROM_NUM]; // for simplicity only support 1 device
static volatile bool _disk_busy[CDROM_NUM];
static FATFS fatfs; // for simplicity only support 1 device
static volatile bool _disk_busy;
static uint8_t mounted_dev;
// define the buffer to be place in USB/DMA memory with correct alignment/cache line size
CFG_TUH_MEM_SECTION static struct {
@@ -47,128 +47,85 @@ CFG_TUH_MEM_SECTION static struct {
bool msc_app_init(void)
{
for(size_t i=0; i<CDROM_NUM; i++) {
_disk_busy[i] = false;
}
// disable stdout buffered for echoing typing command
#ifndef __ICCARM__ // TODO IAR doesn't support stream control ?
setbuf(stdout, NULL);
#endif
return true;
}
void msc_app_task(void)
{
_disk_busy = false;
return true;
}
static bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data) {
msc_cbw_t const* cbw = cb_data->cbw;
msc_csw_t const* csw = cb_data->csw;
msc_cbw_t const* cbw = cb_data->cbw;
msc_csw_t const* csw = cb_data->csw;
if (csw->status != 0)
{
printf("Inquiry failed\r\n");
return false;
}
if (csw->status != 0) {
printf("Inquiry failed\r\n");
return false;
}
// Print out Vendor ID, Product ID and Rev
printf("%.8s %.16s rev %.4s\r\n", scsi_resp.inquiry.vendor_id, scsi_resp.inquiry.product_id, scsi_resp.inquiry.product_rev);
// Print out Vendor ID, Product ID and Rev
printf("%.8s %.16s rev %.4s\r\n", scsi_resp.inquiry.vendor_id, scsi_resp.inquiry.product_id, scsi_resp.inquiry.product_rev);
// Get capacity of device
uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun);
uint32_t const block_size = tuh_msc_get_block_size(dev_addr, cbw->lun);
// Get capacity of device
uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun);
uint32_t const block_size = tuh_msc_get_block_size(dev_addr, cbw->lun);
printf("Disk Size: %" PRIu32 " MB\r\n", block_count / ((1024*1024)/block_size));
// printf("Block Count = %lu, Block Size: %lu\r\n", block_count, block_size);
printf("Disk Size: %" PRIu32 " MB\r\n", block_count / ((1024*1024)/block_size));
// printf("Block Count = %lu, Block Size: %lu\r\n", block_count, block_size);
// For simplicity: we only mount 1 LUN per device
uint8_t const drive_num = dev_addr-1;
char drive_path[3] = "0:";
drive_path[0] += drive_num;
// For simplicity: we only mount 1 device
if (f_mount(&fatfs, "", 1) != FR_OK) {
puts("mount failed");
return false;
}
if ( f_mount(&fatfs[drive_num], drive_path, 1) != FR_OK )
{
puts("mount failed");
return false;
}
// get the drive serial so we can detect if it is reinserted
uint32_t serial;
if (FR_OK != f_getlabel("", NULL, &serial)) {
return false;
}
cdman_set_serial(&cdrom, serial);
// change to newly mounted drive
if (f_chdir(drive_path) != FR_OK) {
puts("chdir failed");
return false;
}
// print the drive label
uint32_t serial;
if ( FR_OK != f_getlabel(drive_path, NULL, &serial) ) {
return false;
}
cdman_set_serial(&cdrom[drive_num], serial);
return true;
return true;
}
//------------- IMPLEMENTATION -------------//
void tuh_msc_mount_cb(uint8_t dev_addr)
{
printf("A MassStorage device is mounted\r\n");
if (dev_addr > 1) {
// Only handle a single drive for now
printf("Only a single USB drive is supported\n");
return;
}
uint8_t const lun = 0;
tuh_msc_inquiry(dev_addr, lun, &scsi_resp.inquiry, inquiry_complete_cb, 0);
printf("A MassStorage device is mounted\r\n");
if (mounted_dev) {
// Only handle a single drive
printf("Only a single USB drive is supported\n");
return;
}
mounted_dev = dev_addr; // may not actually be mounted, but does indicate the drive is inserted
uint8_t const lun = 0;
tuh_msc_inquiry(dev_addr, lun, &scsi_resp.inquiry, inquiry_complete_cb, 0);
}
void tuh_msc_umount_cb(uint8_t dev_addr)
{
printf("A MassStorage device is unmounted\r\n");
if (dev_addr > 1) {
// Only handle a single drive for now
printf("Only a single USB drive is supported\n");
return;
}
(void)dev_addr;
printf("A MassStorage device is unmounted\r\n");
mounted_dev = 0;
uint8_t const drive_num = dev_addr-1;
char drive_path[3] = "0:";
drive_path[0] += drive_num;
f_unmount("");
f_unmount(drive_path);
cdman_unload_image(&cdrom[drive_num]);
// if ( phy_disk == f_get_current_drive() )
// { // active drive is unplugged --> change to other drive
// for(uint8_t i=0; i<CDROM_NUM; i++)
// {
// if ( disk_is_ready(i) )
// {
// f_chdrive(i);
// cli_init(); // refractor, rename
// }
// }
// }
cdman_unload_image(&cdrom);
}
//--------------------------------------------------------------------+
// DiskIO
//--------------------------------------------------------------------+
static void wait_for_disk_io(BYTE pdrv)
static void wait_for_disk_io(void)
{
while(_disk_busy[pdrv])
{
tuh_task();
}
while (_disk_busy) {
tuh_task();
}
}
static bool disk_io_complete(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data)
{
(void) dev_addr; (void) cb_data;
_disk_busy[dev_addr-1] = false;
_disk_busy = false;
return true;
}
@@ -195,14 +152,14 @@ DRESULT disk_read (
UINT count /* Number of sectors to read */
)
{
uint8_t const dev_addr = pdrv + 1;
uint8_t const lun = 0;
(void)pdrv;
uint8_t const lun = 0;
_disk_busy[pdrv] = true;
tuh_msc_read10(dev_addr, lun, buff, sector, (uint16_t) count, disk_io_complete, 0);
wait_for_disk_io(pdrv);
_disk_busy = true;
tuh_msc_read10(mounted_dev, lun, buff, sector, (uint16_t) count, disk_io_complete, 0);
wait_for_disk_io();
return RES_OK;
return RES_OK;
}
#if FF_FS_READONLY == 0
@@ -214,14 +171,14 @@ DRESULT disk_write (
UINT count /* Number of sectors to write */
)
{
uint8_t const dev_addr = pdrv + 1;
uint8_t const lun = 0;
(void)pdrv;
uint8_t const lun = 0;
_disk_busy[pdrv] = true;
tuh_msc_write10(dev_addr, lun, buff, sector, (uint16_t) count, disk_io_complete, 0);
wait_for_disk_io(pdrv);
_disk_busy = true;
tuh_msc_write10(mounted_dev, lun, buff, sector, (uint16_t) count, disk_io_complete, 0);
wait_for_disk_io();
return RES_OK;
return RES_OK;
}
#endif
@@ -232,29 +189,28 @@ DRESULT disk_ioctl (
void *buff /* Buffer to send/receive control data */
)
{
uint8_t const dev_addr = pdrv + 1;
uint8_t const lun = 0;
switch ( cmd )
{
(void)pdrv;
uint8_t const lun = 0;
switch (cmd) {
case CTRL_SYNC:
// nothing to do since we do blocking
return RES_OK;
// nothing to do since we do blocking
return RES_OK;
case GET_SECTOR_COUNT:
*((DWORD*) buff) = (WORD) tuh_msc_get_block_count(dev_addr, lun);
return RES_OK;
*((DWORD*) buff) = (WORD) tuh_msc_get_block_count(mounted_dev, lun);
return RES_OK;
case GET_SECTOR_SIZE:
*((WORD*) buff) = (WORD) tuh_msc_get_block_size(dev_addr, lun);
return RES_OK;
*((WORD*) buff) = (WORD) tuh_msc_get_block_size(mounted_dev, lun);
return RES_OK;
case GET_BLOCK_SIZE:
*((DWORD*) buff) = 1; // erase block size in units of sector size
return RES_OK;
*((DWORD*) buff) = 1; // erase block size in units of sector size
return RES_OK;
default:
return RES_PARERR;
}
return RES_PARERR;
}
return RES_OK;
return RES_OK;
}
+1 -1
View File
@@ -153,7 +153,7 @@
/ on character encoding. When LFN is not enabled, these options have no effect. */
#define FF_FS_RPATH 1
#define FF_FS_RPATH 0
/* This option configures support for relative path.
/
/ 0: Disable relative path and remove related API functions.
+71 -69
View File
@@ -97,86 +97,86 @@ void MKE_COMMAND(uint8_t value) {
if(mke.command_buffer[0] == CMD1_ABORT) {
mke_log("CMD_ABORT\n");
cdrom_fifo_clear(&cdrom[0].info_fifo);
cdrom_fifo_clear(&cdrom.info_fifo);
mke.command_buffer[0]=0;
mke.command_buffer_pending=7;
cdrom_output_status(&cdrom[0]);
cdrom_output_status(&cdrom);
}
if(!mke.command_buffer_pending && mke.command_buffer[0]) { // We are done and we have a command
switch(mke.command_buffer[0]) {
case 06: //TRAY OUT
cdrom_fifo_clear(&cdrom[0].info_fifo);
cdrom_fifo_clear(&cdrom.info_fifo);
mke_log("TRAY OUT\n");
cdrom_output_status(&cdrom[0]);
cdrom_output_status(&cdrom);
mke.tray_open=true;
break;
case 07: //TRAY IN
cdrom_fifo_clear(&cdrom[0].info_fifo);
cdrom_fifo_clear(&cdrom.info_fifo);
mke_log("TRAY IN\n");
cdrom_output_status(&cdrom[0]);
cdrom_output_status(&cdrom);
mke.tray_open=false;
break;
case CMD1_READ:
cdrom[0].req_m=mke.command_buffer[1];
cdrom[0].req_s=mke.command_buffer[2];
cdrom[0].req_f=mke.command_buffer[3];
cdrom[0].req_cur=0;
cdrom[0].req_total=mke.command_buffer[6];
/* printf("r %u ", cdrom[0].req_total); */
cdrom_fifo_clear(&cdrom[0].info_fifo);
cdrom.req_m=mke.command_buffer[1];
cdrom.req_s=mke.command_buffer[2];
cdrom.req_f=mke.command_buffer[3];
cdrom.req_cur=0;
cdrom.req_total=mke.command_buffer[6];
/* printf("r %u ", cdrom.req_total); */
cdrom_fifo_clear(&cdrom.info_fifo);
break;
case CMD1_READSUBQ:
cdrom_get_subq(&cdrom[0],(uint8_t *)&x);
cdrom_fifo_clear(&cdrom[0].info_fifo);
cdrom_fifo_write_multiple(&cdrom[0].info_fifo, x, 11);
cdrom_get_subq(&cdrom,(uint8_t *)&x);
cdrom_fifo_clear(&cdrom.info_fifo);
cdrom_fifo_write_multiple(&cdrom.info_fifo, x, 11);
/*
for(i=0;i<11;i++) {
cdrom_fifo_write(&cdrom[0].info_fifo,x[i]);
cdrom_fifo_write(&cdrom.info_fifo,x[i]);
}
*/
cdrom_output_status(&cdrom[0]);
cdrom_output_status(&cdrom);
break;
case CMD1_SETMODE: //Returns 1
cdrom_fifo_clear(&cdrom[0].info_fifo);
cdrom_fifo_clear(&cdrom.info_fifo);
mke_log("CMD: SET MODE:");
for(i=0;i<6;i++) {
mke_log("%02x ",mke.command_buffer[i+1]);
}
mke_log("\n");
cdrom_output_status(&cdrom[0]);
cdrom_output_status(&cdrom);
break;
case CMD1_GETMODE://6
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]);
cdrom_fifo_write_multiple(&cdrom.info_fifo, mode, 5);
cdrom_output_status(&cdrom);
break;
case CMD1_PAUSERESUME:
cdrom_audio_pause_resume(&cdrom[0],mke.command_buffer[1] >> 7);
cdrom_output_status(&cdrom[0]);
cdrom_audio_pause_resume(&cdrom,mke.command_buffer[1] >> 7);
cdrom_output_status(&cdrom);
break;
case CMD1_CAPACITY://6
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]);
cdrom_disc_capacity(&cdrom, (uint8_t *)&x);
cdrom_fifo_write_multiple(&cdrom.info_fifo, x, 5);
cdrom_output_status(&cdrom);
break;
case CMD1_DISKINFO: //7
mke_log("DISK INFO\n");
cdrom_disc_info(&cdrom[0], (uint8_t *)&x);
cdrom_fifo_write_multiple(&cdrom[0].info_fifo, x, 6);
cdrom_disc_info(&cdrom, (uint8_t *)&x);
cdrom_fifo_write_multiple(&cdrom.info_fifo, x, 6);
/*
for(i=0;i<6;i++) {
mke_log("%02x ",x[i]);
cdrom_fifo_write(&cdrom[0].info_fifo,x[i]);
cdrom_fifo_write(&cdrom.info_fifo,x[i]);
}
mke_log("\n");
*/
cdrom_output_status(&cdrom[0]);
cdrom_output_status(&cdrom);
break;
case CMD1_READTOC:
cdrom_fifo_clear(&cdrom[0].info_fifo);
cdrom_fifo_clear(&cdrom.info_fifo);
/*
mke_log("READ TOC:");
for(i=0;i<6;i++) {
@@ -184,25 +184,25 @@ void MKE_COMMAND(uint8_t value) {
}
mke_log(" | ");
*/
cdrom_read_toc(&cdrom[0],(uint8_t *)&x,mke.command_buffer[2]);
cdrom_fifo_write_multiple(&cdrom[0].info_fifo, x, 8);
cdrom_read_toc(&cdrom,(uint8_t *)&x,mke.command_buffer[2]);
cdrom_fifo_write_multiple(&cdrom.info_fifo, x, 8);
/*
for(i=0;i<8;i++) {
mke_log("%02x ",x[i]);
cdrom_fifo_write(&cdrom[0].info_fifo,x[i]);
cdrom_fifo_write(&cdrom.info_fifo,x[i]);
}
*/
/* mke_log("\n"); */
cdrom_output_status(&cdrom[0]);
cdrom_output_status(&cdrom);
break;
case CMD1_PLAY_MSF:
cdrom_fifo_clear(&cdrom[0].info_fifo);
cdrom_fifo_clear(&cdrom.info_fifo);
mke_log("PLAY MSF:");
for(i=0;i<6;i++) {
mke_log("%02x ",mke.command_buffer[i+1]);
}
mke_log("\n");
cdrom_audio_playmsf(&cdrom[0],
cdrom_audio_playmsf(&cdrom,
mke.command_buffer[1],
mke.command_buffer[2],
mke.command_buffer[3],
@@ -210,51 +210,51 @@ void MKE_COMMAND(uint8_t value) {
mke.command_buffer[5],
mke.command_buffer[6]
);
cdrom_output_status(&cdrom[0]);
cdrom_output_status(&cdrom);
break;
case CMD1_SEEK :
cdrom_fifo_clear(&cdrom[0].info_fifo);
cdrom_fifo_clear(&cdrom.info_fifo);
mke_log("SEEK MSF:"); //TODO: DOES THIS IMPACT CURRENT PLAY LENGTH?
for(i=0;i<6;i++) {
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]);
cdrom_seek(&cdrom,mke.command_buffer[1],mke.command_buffer[2],mke.command_buffer[3]);
cdrom_output_status(&cdrom);
break;
case CMD1_SESSINFO:
cdrom_fifo_clear(&cdrom[0].info_fifo);
cdrom_fifo_clear(&cdrom.info_fifo);
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]);
cdrom_fifo_write_multiple(&cdrom.info_fifo, session_info, 6);
cdrom_output_status(&cdrom);
break;
case CMD1_READ_UPC:
cdrom_fifo_clear(&cdrom[0].info_fifo);
cdrom_fifo_clear(&cdrom.info_fifo);
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]);
cdrom_fifo_write_multiple(&cdrom.info_fifo, upc, 8);
cdrom_output_status(&cdrom);
break;
case CMD1_READ_ERR:
cdrom_fifo_clear(&cdrom[0].info_fifo);
cdrom_fifo_clear(&cdrom.info_fifo);
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]);
cdrom_read_errors(&cdrom,(uint8_t *)x);
cdrom_fifo_write_multiple(&cdrom.info_fifo, x, 8);
cdrom_output_status(&cdrom);
break;
case CMD1_READ_VER:
/*
SB2CD Expects 12 bytes, but drive only returns 11.
*/
cdrom_fifo_clear(&cdrom[0].info_fifo);
cdrom_fifo_clear(&cdrom.info_fifo);
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]);
cdrom_fifo_write_multiple(&cdrom.info_fifo, ver, 10);
cdrom_output_status(&cdrom);
break;
case CMD1_STATUS:
cdrom_fifo_clear(&cdrom[0].info_fifo);
cdrom_output_status(&cdrom[0]);
cdrom_fifo_clear(&cdrom.info_fifo);
cdrom_output_status(&cdrom);
break;
default:
mke_log("MKE: Unknown Commnad [%02x]\n",mke.command_buffer[0]);
@@ -299,11 +299,11 @@ uint8_t MKE_READ(uint16_t address) {
switch(address & 0xF) {
case 0://Info
if(mke.data_select) {
return cdrom_fifo_read(&cdrom[0].data_fifo);
return cdrom_fifo_read(&cdrom.data_fifo);
}
else {
return cdrom_fifo_read(&cdrom[0].info_fifo);
return cdrom_fifo_read(&cdrom.info_fifo);
}
break;
case 1://Status
@@ -314,14 +314,14 @@ uint8_t MKE_READ(uint16_t address) {
8 = Attention / Issue ?
*/
x=0xFF;
//if(cdrom[0].media_changed) x ^= 1;
if(cdrom_fifo_level(&cdrom[0].data_fifo)) x ^= 2;//DATA FIFO
if(cdrom_fifo_level(&cdrom[0].info_fifo)) x ^= 4;//STATUS FIFO
if(cdrom_has_errors(&cdrom[0])) x ^=8;
//if(cdrom.media_changed) x ^= 1;
if(cdrom_fifo_level(&cdrom.data_fifo)) x ^= 2;//DATA FIFO
if(cdrom_fifo_level(&cdrom.info_fifo)) x ^= 4;//STATUS FIFO
if(cdrom_has_errors(&cdrom)) x ^=8;
return x;
break;
case 2://Data
return cdrom_fifo_read(&cdrom[0].data_fifo);
return cdrom_fifo_read(&cdrom.data_fifo);
case 3:
return mke.enable_register;
break;
@@ -336,13 +336,15 @@ uint8_t MKE_READ(uint16_t address) {
void mke_init() {
cdrom_fifo_init(&cdrom[0].data_fifo,2048+2048);
cdrom_fifo_init(&cdrom[0].info_fifo,32);
cdrom_audio_fifo_init(&cdrom[0]);
mke_log("FIFOS, INFO=%p DATA=%p\n",cdrom[0].info_fifo,cdrom[0].data_fifo);
cdrom_fifo_init(&cdrom.data_fifo,2048+2048);
cdrom_fifo_init(&cdrom.info_fifo,32);
#if USE_CD_AUDIO_FIFO
cdrom_audio_fifo_init(&cdrom);
#endif
mke_log("FIFOS, INFO=%p DATA=%p\n",cdrom.info_fifo,cdrom.data_fifo);
mke.command_buffer_pending=7;
cdrom[0].sound_on=1;
cdrom.sound_on=1;
}
+15 -15
View File
@@ -81,10 +81,9 @@ 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];
cdrom_t cdrom;
static uint32_t cur_read_idx;
#endif
@@ -226,9 +225,9 @@ __force_inline void select_picogus(uint8_t value) {
break;
case MODE_CDLIST:
#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;
if (cdrom.image_status != CD_STATUS_READY) {
cdrom.image_status = CD_STATUS_BUSY;
cdrom.image_command = CD_COMMAND_IMAGE_LIST;
puts("cdimages start");
}
puts("cdimages read");
@@ -394,9 +393,9 @@ __force_inline void write_picogus_high(uint8_t value) {
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;
cdrom.image_data = value;
cdrom.image_status = CD_STATUS_BUSY;
cdrom.image_command = CD_COMMAND_IMAGE_LOAD_INDEX;
break;
#endif
case MODE_CDAUTOADV: // enable auto advance of CD image on USB reinsert
@@ -525,16 +524,16 @@ __force_inline uint8_t read_picogus_high(void) {
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;
printf("cdstatus %x\n", cdrom.image_status);
return cdrom.image_status;
case MODE_CDLIST:
if (cur_read_idx == cdrom[0].image_count) { // If end of the images
if (cur_read_idx == cdrom.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);
cdrom.image_status = CD_STATUS_IDLE;
cdman_list_images_free(cdrom.image_list, cdrom.image_count);
return 0x04; // EOT
}
ret = cdrom[0].image_list[cur_read_idx][cur_read++];
ret = cdrom.image_list[cur_read_idx][cur_read++];
putchar(ret);
if (ret == 0) { // Null terminated
++cur_read_idx;
@@ -544,7 +543,7 @@ __force_inline uint8_t read_picogus_high(void) {
case MODE_CDLOAD: // Load CD image
return cdman_current_image_index();
case MODE_CDNAME: // Firmware string
ret = cdrom[0].image_path[cur_read++];
ret = cdrom.image_path[cur_read++];
if (ret == 0) { // Null terminated
cur_read = 0;
}
@@ -1150,6 +1149,7 @@ int main()
#endif
#ifdef CDROM
cdrom_global_init();
mke_init();
#endif
+39 -54
View File
@@ -53,7 +53,7 @@ extern audio_fifo_t* sbdsp_fifo_peek();
#if CDROM
#include "cdrom/cdrom.h"
extern cdrom_t cdrom[CDROM_NUM];
// extern cdrom_t cdrom;
#endif // CDROM
#include "clamp.h"
@@ -174,9 +174,8 @@ void play_adlib() {
uint32_t sb_state = FIFO_STATE_STOPPED;
#endif
#ifdef CDROM
audio_fifo_t* cd_fifo = cdrom_audio_fifo_peek(&cdrom[0]);
int16_t cd_samples[SAMPLES_PER_BUFFER * 2];
bool has_samples;
bool has_cd_samples;
#endif
#ifdef SOUND_SB
@@ -205,75 +204,61 @@ void play_adlib() {
int32_t accum[2] = {0};
for (;;) {
// cdrom_audio_callback(&cdrom[0], cd_samples, 1024);
#if CDROM
has_cd_samples = cdrom_audio_callback_simple(&cdrom, cd_samples, SAMPLES_PER_BUFFER << 1, true);
#endif
struct audio_buffer *buffer = take_audio_buffer(ap, true);
int16_t *samples = (int16_t *) buffer->buffer->bytes;
// Do mixing with lerp
has_samples = cdrom_audio_callback_simple(&cdrom[0], cd_samples, SAMPLES_PER_BUFFER << 1, true);
//
#if !SB_BUFFERLESS
for (int i = 0; i < SAMPLES_PER_BUFFER; ++i) {
#endif // !SB_BUFFERLESS
accum[0] = accum[1] = 0;
#if CDROM
if (has_samples) {
if (has_cd_samples) {
accum[0] += cd_samples[i << 1];
accum[1] += cd_samples[(i << 1) + 1];
}
/*
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)) {
cd_left = AUDIO_FIFO_SIZE;
// putchar('c');
} else {
// putchar('f');
}
}
if (cd_left) {
accum[0] += cd_fifo->buffer[cd_index & AUDIO_FIFO_BITS];
accum[1] += cd_fifo->buffer[(cd_index + 1) & AUDIO_FIFO_BITS];
// accum[0] += cd_samples[cd_index & 1023];
// accum[1] += cd_samples[(cd_index + 1) & 1023];
cd_index = (cd_index + 2) & AUDIO_FIFO_BITS;
cd_left -= 2;
}
*/
#endif // CDROM
uint32_t opl_index = (opl_pos >> FRAC_BITS);
// uint32_t opl_index = i;
uint32_t opl_frac = opl_pos & FRAC_MASK;
opl_pos += opl_ratio;
uint32_t opl_index = (opl_pos >> FRAC_BITS);
// uint32_t opl_index = i;
uint32_t opl_frac = opl_pos & FRAC_MASK;
opl_pos += opl_ratio;
// printf("%x %x\n", opl_index, opl_frac);
// printf("%x %x\n", opl_index, opl_frac);
#if !SB_BUFFERLESS // don't support OPL in bufferless for now
if (
((opl_index & 0x100) && opl_sample_idx != 0x0) ||
(!(opl_index & 0x100) && opl_sample_idx != 0x100)
) {
opl_sample_idx = (opl_index + 0x100) & 0x100;
/*
bool notfirst = false;
while (opl_buffer.tail != opl_buffer.head) {
if (!notfirst) {
if (
((opl_index & SAMPLES_PER_BUFFER) && opl_sample_idx != 0x0) ||
(!(opl_index & SAMPLES_PER_BUFFER) && opl_sample_idx != SAMPLES_PER_BUFFER)
) {
opl_sample_idx = (opl_index + SAMPLES_PER_BUFFER) & SAMPLES_PER_BUFFER;
/*
bool notfirst = false;
while (opl_buffer.tail != opl_buffer.head) {
if (!notfirst) {
#ifndef PICOW
gpio_xor_mask(LED_PIN);
gpio_xor_mask(LED_PIN);
#endif
notfirst = true;
notfirst = true;
}
auto cmd = opl_buffer.cmds[opl_buffer.tail];
OPL_Pico_PortWrite((opl_port_t)cmd.addr, cmd.data);
++opl_buffer.tail;
}
auto cmd = opl_buffer.cmds[opl_buffer.tail];
OPL_Pico_PortWrite((opl_port_t)cmd.addr, cmd.data);
++opl_buffer.tail;
*/
OPL_Pico_simple(opl_samples + opl_sample_idx, SAMPLES_PER_BUFFER);
}
*/
OPL_Pico_simple(opl_samples + opl_sample_idx, SAMPLES_PER_BUFFER);
}
int32_t opl_sample = lerp_fixed(
opl_samples[opl_index & 0x1ff],
opl_samples[(opl_index + 1) & 0x1ff],
opl_frac);
accum[0] += opl_samples[opl_index & 0x1ff];
accum[1] += opl_samples[opl_index & 0x1ff];
int32_t opl_sample = lerp_fixed(
opl_samples[opl_index & 0x1ff],
opl_samples[(opl_index + 1) & 0x1ff],
opl_frac);
accum[0] += opl_samples[opl_index & 0x1ff];
accum[1] += opl_samples[opl_index & 0x1ff];
#if CDROM
//}
#endif
#if SOUND_SB
if (!sb_left) {
// putchar('t');
@@ -341,7 +326,7 @@ void play_adlib() {
send_midi_bytes(1);
#endif
#ifdef CDROM
cdrom_tasks(&cdrom[0]);
cdrom_tasks(&cdrom);
#endif
}
}
+3 -4
View File
@@ -25,7 +25,6 @@
// #include <string.h>
#ifdef CDROM
#include "cdrom/cdrom.h"
extern cdrom_t cdrom[CDROM_NUM];
#include "pico/audio_i2s.h"
#endif
@@ -89,10 +88,10 @@ void play_usb() {
#endif
for (;;) {
#ifdef CDROM
if (cdrom[0].cd_status == CD_STATUS_PLAYING) {
if (cdrom.cd_status == CD_STATUS_PLAYING) {
struct audio_buffer *buffer = take_audio_buffer(ap, true);
int16_t *samples = (int16_t *) buffer->buffer->bytes;
buffer->sample_count = cdrom_audio_callback_simple(&cdrom[0], samples, SAMPLES_PER_BUFFER << 1, false) >> 1;
buffer->sample_count = cdrom_audio_callback_simple(&cdrom, samples, SAMPLES_PER_BUFFER << 1, false) >> 1;
if (buffer->sample_count == 0) {
// If we got no samples back, playback stopped so output a sample of silence
// (give_audio_buffer does not tolerate 0 samples, so we have to emit 1)
@@ -101,7 +100,7 @@ void play_usb() {
}
give_audio_buffer(ap, buffer);
}
cdrom_tasks(&cdrom[0]);
cdrom_tasks(&cdrom);
#endif // CDROM
// tinyusb host task
tuh_task();