forked from notaz/picodrive
-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
like msu-md. loading a .cue file will look for a cartridge image with the same basename and an extension of "gen", "smd", "md", "32x".
- Loading branch information
Showing
8 changed files
with
287 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,256 @@ | ||
/* | ||
* PicoDrive | ||
* (C) irixxxx, 2024 | ||
* | ||
* MEGASD enhancement support | ||
*/ | ||
|
||
#include "../pico_int.h" | ||
#include "../memory.h" | ||
|
||
#include "genplus_macros.h" | ||
#include "cdd.h" | ||
#include "megasd.h" | ||
|
||
// modifiable fields visible through the interface | ||
u16 msd_command, msd_result; | ||
u16 msd_data[0x800/2]; | ||
|
||
// internal state | ||
static int msd_initialized; | ||
static s32 msd_startlba, msd_endlba, msd_looplba; | ||
static s32 msd_readlba = -1; // >= 0 if sector read is running | ||
static int msd_loop, msd_index = -1; // >= 0 if audio track is playing | ||
|
||
static u16 verser[] = // mimick version 1.04 R7, serial 0x01234567 | ||
{ 0x4d45, 0x4741, 0x5344, 0x0104, 0x0700, 0xffff, 0x0123, 0x4567 }; | ||
// { 0x4d45, 0x4741, 0x5344, 0x9999, 0x9900, 0xffff, 0x1234, 0x5678 }; | ||
|
||
// get a 32bit value from the data area | ||
static s32 get32(int offs) | ||
{ | ||
u16 *a = msd_data + (offs/2); | ||
return (a[0] << 16) | a[1]; | ||
} | ||
|
||
// send commands to cdd | ||
static void cdd_play(s32 lba) | ||
{ | ||
int secs = lba / 75; | ||
int mins = secs / 60; | ||
lba -= secs * 75; | ||
secs -= mins * 60; | ||
s68k_write8(0xff8044, mins/10); | ||
s68k_write8(0xff8045, mins%10); | ||
s68k_write8(0xff8046, secs/10); | ||
s68k_write8(0xff8047, secs%10); | ||
s68k_write8(0xff8048, lba /10); | ||
s68k_write8(0xff8049, lba %10); | ||
|
||
s68k_write8(0xff8042, 0x03); | ||
s68k_write8(0xff804b, 0xff); | ||
} | ||
|
||
static void cdd_pause(void) | ||
{ | ||
s68k_write8(0xff8042, 0x06); | ||
s68k_write8(0xff804b, 0xff); | ||
} | ||
|
||
static void cdd_resume(void) | ||
{ | ||
s68k_write8(0xff8042, 0x07); | ||
s68k_write8(0xff804b, 0xff); | ||
} | ||
|
||
static void cdd_stop(void) | ||
{ | ||
msd_index = msd_readlba = -1; | ||
s68k_write8(0xff8042, 0x01); | ||
s68k_write8(0xff804b, 0xff); | ||
} | ||
|
||
// play a track, looping from offset if enabled | ||
static void msd_playtrack(int idx, s32 offs, int loop) | ||
{ | ||
msd_index = idx-1; | ||
msd_loop = loop; | ||
msd_readlba = -1; | ||
|
||
msd_startlba = cdd.toc.tracks[msd_index].start + 150; | ||
msd_endlba = cdd.toc.tracks[msd_index].end; | ||
msd_looplba = msd_startlba + offs; | ||
|
||
cdd_play(msd_startlba); | ||
} | ||
|
||
// play a range of sectors, with looping if enabled | ||
static void msd_playsectors(s32 startlba, s32 endlba, s32 looplba, int loop) | ||
{ | ||
msd_index = 99; | ||
msd_loop = loop; | ||
msd_readlba = -1; | ||
|
||
msd_startlba = startlba + 150; | ||
msd_endlba = endlba + 150; | ||
msd_looplba = looplba + 150; | ||
|
||
cdd_play(msd_startlba); | ||
} | ||
|
||
// read a block of data | ||
static void msd_readdata(s32 lba) | ||
{ | ||
msd_index = -1; | ||
msd_readlba = lba; | ||
|
||
cdd_play(msd_readlba); | ||
} | ||
|
||
// transfer data to data area | ||
static void msd_transfer() | ||
{ | ||
if (cdd.status == CD_PLAY) | ||
cdd_read_data((u8 *)msd_data); | ||
|
||
// transfer done | ||
msd_command = 0; | ||
} | ||
|
||
// update msd state (called every 1/75s) | ||
void msd_update() | ||
{ | ||
if (msd_initialized) { | ||
// CD LEDs | ||
s68k_write8(0xff8000,(cdd.status == CD_PLAY) | 0x2); | ||
|
||
if (cdd.status == CD_PLAY) { | ||
if (msd_readlba >= 0 && cdd.lba >= msd_readlba) { | ||
// read done | ||
msd_command = 0; | ||
} | ||
else if (msd_index >= 0 && (cdd.lba > msd_endlba || cdd.index > msd_index)) { | ||
if (!msd_loop || msd_index < 0) { | ||
cdd_stop(); | ||
// audio done | ||
msd_command = 0; | ||
} else | ||
cdd_play(msd_looplba); | ||
} | ||
} | ||
} | ||
} | ||
|
||
// process a MEGASD command | ||
void msd_process(u16 d) | ||
{ | ||
msd_command = d; // busy | ||
|
||
switch (d >> 8) { | ||
case 0x10: memcpy(msd_data, verser, sizeof(verser)); msd_command = 0; break; | ||
|
||
case 0x11: msd_playtrack(d&0xff, 0, 0); break; | ||
case 0x12: msd_playtrack(d&0xff, 0, 1); break; | ||
case 0x1a: msd_playtrack(d&0xff, get32(0), 1); break; | ||
case 0x1b: msd_playsectors(get32(0), get32(4), get32(8), d&0xff); break; | ||
|
||
case 0x13: cdd_pause(); break; | ||
case 0x14: cdd_resume(); break; | ||
|
||
case 0x16: msd_result = !(s68k_read8(0xff8036) & 0x1) << 8; | ||
msd_command = 0; break; | ||
|
||
case 0x17: msd_readdata(get32(0)); break; | ||
case 0x18: msd_transfer(); break; | ||
case 0x19: msd_readdata(++msd_readlba); break; | ||
|
||
case 0x27: msd_result = cdd.toc.last << 8; | ||
msd_command = 0; break; | ||
|
||
default: msd_command = msd_result = 0; break; // not supported | ||
} | ||
} | ||
|
||
// initialize MEGASD | ||
static void msd_init(void) | ||
{ | ||
if (!msd_initialized) { | ||
msd_initialized = 1; | ||
|
||
// enable CD drive | ||
s68k_write8(0xff8037, 0x4); | ||
|
||
PicoResetHook = msd_reset; | ||
} | ||
} | ||
|
||
void msd_reset(void) | ||
{ | ||
if (msd_initialized) { | ||
msd_initialized = msd_command = 0; | ||
cdd_stop(); | ||
|
||
s68k_write8(0xff8000, 0x0); | ||
s68k_write8(0xff8001, 0x0); | ||
|
||
PicoResetHook = NULL; | ||
} | ||
} | ||
|
||
// memory r/w functions | ||
static u32 msd_read16(u32 a) | ||
{ | ||
u16 d = 0; | ||
|
||
if (a >= 0x03f800) { | ||
d = msd_data[(a&0x7ff)>>1]; | ||
} else if (a >= 0x03f7f0) { | ||
switch (a&0xe) { | ||
case 0x6: d = 0x5241; break; // RA | ||
case 0x8: d = 0x5445; break; // TE | ||
case 0xc: d = msd_result; break; | ||
case 0xe: d = msd_command; break; | ||
} | ||
} else if (a < Pico.romsize) | ||
d = *(u16 *)(Pico.rom + a); | ||
|
||
return d; | ||
} | ||
|
||
static u32 msd_read8(u32 a) | ||
{ | ||
u16 d = msd_read16(a); | ||
|
||
if (!(a&1)) d >>= 8; | ||
return d; | ||
} | ||
|
||
void msd_write16(u32 a, u32 d) | ||
{ | ||
if (a == 0x03f7fa) { | ||
// en/disable overlay | ||
u32 base = 0x040000-(1<<M68K_MEM_SHIFT); | ||
if ((u16)d == 0xcd54) { | ||
msd_init(); | ||
cpu68k_map_set(m68k_read8_map, base, 0x03ffff, msd_read8, 1); | ||
cpu68k_map_set(m68k_read16_map, base, 0x03ffff, msd_read16, 1); | ||
} else if (Pico.romsize > base) { | ||
cpu68k_map_set(m68k_read8_map, base, 0x03ffff, Pico.rom+base, 0); | ||
cpu68k_map_set(m68k_read16_map, base, 0x03ffff, Pico.rom+base, 0); | ||
} | ||
} else if (a == 0x03f7fe) { | ||
// command port | ||
msd_process(d); | ||
} else if (a >= 0x03f800) { | ||
// data area | ||
msd_data[(a&0x7ff) >> 1] = d; | ||
} | ||
} | ||
|
||
void msd_write8(u32 a, u32 d) | ||
{ | ||
if (a >= 0x03f800) { | ||
// data area | ||
((u8 *)msd_data)[MEM_BE2(a&0x7ff)] = d; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
|
||
|
||
extern u16 msd_command, msd_result; | ||
extern u16 msd_data[0x800/2]; | ||
|
||
extern void msd_update(void); | ||
extern void msd_process(u16 d); | ||
extern void msd_reset(void); | ||
|
||
extern void msd_write8(u32 a, u32 d); | ||
extern void msd_write16(u32 a, u32 d); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters