ref: 8163706a9f348cc0a0aacaa67434b194aacd9ae1
parent: 32088d682e8b0f1005d012c3313054b852df87c9
author: allkern <lisandroaalarcon@gmail.com>
date: Fri Sep 15 17:16:53 EDT 2023
Implement CdlPlay (CDDA) Fix resolution to multiples of 320x240
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -1,5 +1,6 @@
#include "psx/psx.h"
#include "psx/input/sda.h"
+#include "psx/disc/cue.h"
#include "screen.h"
#include "config.h"
@@ -6,6 +7,12 @@
#undef main
+void audio_update(void* ud, uint8_t* buf, int size) {+ psx_cdrom_t* cdrom = ud;
+
+ psx_cdrom_get_cdda_samples(cdrom, buf, size);
+}
+
int main(int argc, const char* argv[]) {psxe_config_t* cfg = psxe_cfg_create();
@@ -28,6 +35,24 @@
psxe_screen_set_scale(screen, 3);
psxe_screen_reload(screen);
+ SDL_Init(SDL_INIT_AUDIO);
+
+ SDL_AudioDeviceID dev;
+ SDL_AudioSpec obtained, desired;
+
+ desired.freq = 44100;
+ desired.format = AUDIO_S16SYS;
+ desired.channels = 2;
+ desired.samples = CD_SECTOR_SIZE >> 2;
+ desired.callback = &audio_update;
+ desired.userdata = cdrom;
+
+ dev = SDL_OpenAudioDevice(NULL, 0, &desired, &obtained, 0);
+
+ log_fatal("obtained.samples=%u", obtained.samples);+
+ if (dev) SDL_PauseAudioDevice(dev, 0);
+
psx_gpu_t* gpu = psx_get_gpu(psx);
psx_gpu_set_event_callback(gpu, GPU_EVENT_DMODE, psxe_gpu_dmode_event_cb);
psx_gpu_set_event_callback(gpu, GPU_EVENT_VBLANK, psxe_gpu_vblank_event_cb);
@@ -74,7 +99,7 @@
if (cfg->cd_path)
psx_cdrom_destroy(cdrom);
-
+
psx_input_destroy(input);
psx_destroy(psx);
psxi_sda_destroy(controller);
--- a/frontend/screen.c
+++ b/frontend/screen.c
@@ -54,6 +54,14 @@
if (screen->renderer) SDL_DestroyRenderer(screen->renderer);
if (screen->window) SDL_DestroyWindow(screen->window);
+ if (screen->debug_mode) {+ screen->width = PSX_GPU_FB_WIDTH;
+ screen->height = PSX_GPU_FB_HEIGHT;
+ } else {+ screen->width = 320;
+ screen->height = 240;
+ }
+
screen->window = SDL_CreateWindow(
"psxe " STR(REP_VERSION) "-" STR(REP_COMMIT_HASH),
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
@@ -97,6 +105,8 @@
void psxe_screen_toggle_debug_mode(psxe_screen_t* screen) {screen->debug_mode = !screen->debug_mode;
+ psxe_screen_set_scale(screen, screen->saved_scale);
+
psxe_gpu_dmode_event_cb(screen->psx->gpu);
}
@@ -161,6 +171,9 @@
void psxe_gpu_dmode_event_cb(psx_gpu_t* gpu) {psxe_screen_t* screen = gpu->udata[0];
+ int texture_width;
+ int texture_height;
+
screen->format = psx_get_display_format(screen->psx) ?
SDL_PIXELFORMAT_BGR555 : SDL_PIXELFORMAT_RGB888;
@@ -167,16 +180,20 @@
if (screen->debug_mode) {screen->width = PSX_GPU_FB_WIDTH;
screen->height = PSX_GPU_FB_HEIGHT;
+ texture_width = PSX_GPU_FB_WIDTH;
+ texture_height = PSX_GPU_FB_HEIGHT;
} else {- screen->width = psx_get_display_width(screen->psx);
- screen->height = psx_get_display_height(screen->psx);
+ screen->width = 320;
+ screen->height = 240;
+ texture_width = psx_get_display_width(screen->psx);
+ texture_height = psx_get_display_height(screen->psx);
}
- if (screen->width > 512) {- screen->scale = 1;
- } else {- screen->scale = screen->saved_scale;
- }
+ // if (screen->width > 512) {+ // screen->scale = 1;
+ // } else {+ // screen->scale = screen->saved_scale;
+ // }
SDL_DestroyTexture(screen->texture);
@@ -184,7 +201,7 @@
screen->renderer,
SDL_PIXELFORMAT_BGR555,
SDL_TEXTUREACCESS_STREAMING,
- screen->width, screen->height
+ texture_width, texture_height
);
SDL_SetWindowSize(
--- a/psx/dev/cdrom.c
+++ b/psx/dev/cdrom.c
@@ -153,6 +153,61 @@
} break;
}
}
+void cdrom_cmd_play(psx_cdrom_t* cdrom) {+ cdrom->delayed_command = CDL_NONE;
+
+ switch (cdrom->state) {+ case CD_STATE_RECV_CMD: {+ // if (cdrom->pfifo_index) {+ // log_fatal("CdlGetStat: Expected exactly 0 parameters");+
+ // cdrom->irq_delay = DELAY_1MS;
+ // cdrom->delayed_command = CDL_ERROR;
+ // cdrom->state = CD_STATE_ERROR;
+ // cdrom->error = ERR_PCOUNT;
+ // cdrom->error_flags = GETSTAT_ERROR;
+
+ // return;
+ // }
+
+ cdrom->irq_delay = DELAY_1MS;
+ cdrom->state = CD_STATE_SEND_RESP1;
+ cdrom->delayed_command = CDL_PLAY;
+
+ cdrom->cdda_msf.m = cdrom->seek_mm;
+ cdrom->cdda_msf.s = cdrom->seek_ss;
+ cdrom->cdda_msf.f = cdrom->seek_ff;
+
+ // Convert seek to I
+ msf_t msf = cdrom->cdda_msf;
+
+ msf_from_bcd(&msf);
+
+ msf.s -= 24;
+
+ // Seek to that address and read sector
+ psx_disc_seek(cdrom->disc, msf);
+ psx_disc_read_sector(cdrom->disc, cdrom->cdda_buf);
+
+ // Increment sector
+ msf_add_f(&msf, 1);
+ msf_to_bcd(&msf);
+
+ cdrom->cdda_msf = msf;
+
+ cdrom->cdda_sector_offset = 0;
+ cdrom->cdda_playing = 1;
+ } break;
+
+ case CD_STATE_SEND_RESP1: {+ SET_BITS(ifr, IFR_INT, IFR_INT3);
+ RESP_PUSH(GETSTAT_MOTOR | GETSTAT_PLAY);
+
+ cdrom->delayed_command = CDL_NONE;
+ cdrom->state = CD_STATE_RECV_CMD;
+ } break;
+ }
+}
void cdrom_cmd_readn(psx_cdrom_t* cdrom) {cdrom->delayed_command = CDL_NONE;
cdrom->read_ongoing = 1;
@@ -528,7 +583,7 @@
psx_disc_get_track_addr(cdrom->disc, &td, cdrom->gettd_track);
- log_fatal("GetTD track=%u, addr=%02u:%02u", cdrom->gettd_track, td.m, td.s);+ log_fatal("@@@@@@@@@@@@@@@@ GetTD track=%u, addr=%02u:%02u", cdrom->gettd_track, td.m, td.s);// To-do: Handle OOB tracks
@@ -860,9 +915,9 @@
"CdlUnimplemented",
"CdlGetstat",
"CdlSetloc",
+ "CdlPlay",
"CdlUnimplemented",
"CdlUnimplemented",
- "CdlUnimplemented",
"CdlReadn",
"CdlUnimplemented",
"CdlStop",
@@ -895,9 +950,9 @@
cdrom_cmd_unimplemented,
cdrom_cmd_getstat,
cdrom_cmd_setloc,
+ cdrom_cmd_play,
cdrom_cmd_unimplemented,
cdrom_cmd_unimplemented,
- cdrom_cmd_unimplemented,
cdrom_cmd_readn,
cdrom_cmd_unimplemented,
cdrom_cmd_stop,
@@ -1109,6 +1164,8 @@
cdrom->ic = ic;
cdrom->status = STAT_PRMEMPT_MASK | STAT_PRMWRDY_MASK;
+ cdrom->dfifo = malloc(CD_SECTOR_SIZE);
+ cdrom->cdda_buf = malloc(CD_SECTOR_SIZE);
}
uint32_t psx_cdrom_read32(psx_cdrom_t* cdrom, uint32_t offset) {@@ -1236,6 +1293,95 @@
exit(1);
}
+}
+
+void psx_cdrom_get_cdda_samples(psx_cdrom_t* cdrom, void* buf, int size) {+ if (!cdrom->cdda_playing) {+ memset(buf, 0, size);
+
+ return;
+ }
+
+ memcpy(buf, cdrom->cdda_buf, size);
+
+ // Convert seek to I
+ msf_t msf = cdrom->cdda_msf;
+
+ msf_from_bcd(&msf);
+
+ // Seek to that address and read sector
+ psx_disc_seek(cdrom->disc, msf);
+ psx_disc_read_sector(cdrom->disc, cdrom->cdda_buf);
+
+ // Increment sector
+ msf_add_f(&msf, 1);
+ msf_to_bcd(&msf);
+
+ // Assign to CDDA MSF
+ cdrom->cdda_msf = msf;
+
+ /*
+ start = offset
+ end = offset + request
+
+ start = 0
+ end = 10
+
+ */
+
+ // int req_start = cdrom->cdda_sector_offset;
+ // int req_end = req_start + size;
+
+ // if (req_end > CD_SECTOR_SIZE) {+ // int unbuffered = req_end - CD_SECTOR_SIZE;
+ // //int buffered =
+ // }
+
+ // // We need a new sector
+ // if (cdrom->cdda_sector_offset >= CD_SECTOR_SIZE) {+ // cdrom->cdda_sector_offset -= CD_SECTOR_SIZE;
+
+ // // Convert seek to I
+ // msf_t msf = cdrom->cdda_msf;
+
+ // msf_from_bcd(&msf);
+
+ // // Seek to that address and read sector
+ // psx_disc_seek(cdrom->disc, msf);
+ // psx_disc_read_sector(cdrom->disc, cdrom->cdda_buf);
+
+ // // Increment sector
+ // msf_add_f(&msf, 1);
+ // msf_to_bcd(&msf);
+
+ // // Assign to CDDA MSF
+ // cdrom->cdda_msf = msf;
+ // }
+
+ memcpy(buf, cdrom->cdda_buf, size);
+
+ // cdrom->cdda_sector_offset += size;
+
+ // // We need a new sector
+ // if (cdrom->cdda_sector_offset >= CD_SECTOR_SIZE) {+ // cdrom->cdda_sector_offset -= CD_SECTOR_SIZE;
+
+ // // Convert seek to I
+ // msf_t msf = cdrom->cdda_msf;
+
+ // msf_from_bcd(&msf);
+
+ // // Seek to that address and read sector
+ // psx_disc_seek(cdrom->disc, msf);
+ // psx_disc_read_sector(cdrom->disc, cdrom->cdda_buf);
+
+ // // Increment sector
+ // msf_add_f(&msf, 1);
+ // msf_to_bcd(&msf);
+
+ // // Assign to CDDA MSF
+ // cdrom->cdda_msf = msf;
+ // }
}
void psx_cdrom_destroy(psx_cdrom_t* cdrom) {--- a/psx/dev/cdrom.h
+++ b/psx/dev/cdrom.h
@@ -155,8 +155,8 @@
int pfifo_index;
int rfifo_index;
- uint8_t read_buf[CD_SECTOR_SIZE];
- uint8_t dfifo[CD_SECTOR_SIZE];
+ uint8_t* read_buf;
+ uint8_t* dfifo;
int dfifo_index;
int dfifo_full;
@@ -185,6 +185,12 @@
int read_ongoing;
int gettd_track;
+ // CDDA
+ uint8_t* cdda_buf;
+ int cdda_sector_offset;
+ msf_t cdda_msf;
+ int cdda_playing;
+
const char* path;
psx_disc_t* disc;
} psx_cdrom_t;
@@ -200,6 +206,7 @@
void psx_cdrom_update(psx_cdrom_t*);
void psx_cdrom_destroy(psx_cdrom_t*);
void psx_cdrom_open(psx_cdrom_t*, const char*);
+void psx_cdrom_get_cdda_samples(psx_cdrom_t*, void*, int);
/*
Command Parameters Response(s)
@@ -251,6 +258,7 @@
void cdrom_cmd_unimplemented(psx_cdrom_t*);
void cdrom_cmd_getstat(psx_cdrom_t*);
void cdrom_cmd_setloc(psx_cdrom_t*);
+void cdrom_cmd_play(psx_cdrom_t*);
void cdrom_cmd_readn(psx_cdrom_t*);
void cdrom_cmd_stop(psx_cdrom_t*);
void cdrom_cmd_pause(psx_cdrom_t*);
--
⑨