33 #include <sys/types.h>
38 #ifndef CONFIG_SDEXT_SUPPORT
39 #warning "SDEXT support is disabled by configuration."
44 # define SD_DEBUG DEBUG
46 # define SD_DEBUG(...)
50 int sdext_enabled = 0;
52 static int rom_page_ofs = 0;
53 static int is_hs_read;
54 static Uint8 _spi_last_w;
59 static Uint8 sd_ram_ext[7 * 1024];
60 static Uint8 sd_rom_ext[SDCARD_ROM_SIZE];
62 static Uint8 cmd[6], cmd_index, _read_b, _write_b, _write_specified;
63 static const Uint8 *ans_p;
64 static int ans_index, ans_size;
66 static int delay_answer;
67 static void (*ans_callback)(void);
70 static Uint8 _buffer[1024];
71 off_t sd_card_size = 0;
73 #define MAX_CARD_SIZE 2147483648UL
74 #define MIN_CARD_SIZE 8388608UL
86 static const Uint8 _stop_transmission_answer[] = {
91 #define CSD(a) _read_csd_answer[(__CSD_OFS) + (a)]
92 static Uint8 _read_csd_answer[] = {
96 0x00, 0x5D, 0x01, 0x32, 0x13, 0x59, 0x80, 0xE3, 0x76, 0xD9, 0xCF, 0xFF, 0x16, 0x40, 0x00, 0x4F,
99 static const Uint8 _read_cid_answer[] = {
103 0x01, 0x50, 0x41, 0x53, 0x30, 0x31, 0x36, 0x42, 0x41, 0x35, 0xE4, 0x39, 0x06, 0x00, 0x35, 0x03,
106 static const Uint8 _read_ocr_answer[] = {
108 0x80, 0xFF, 0x80, 0x00
111 #define ADD_ANS(ans) { ans_p = (ans); ans_index = 0; ans_size = sizeof(ans); }
114 #include "xemu/../rom/ep128/vhd_compressed.c"
115 static int decompress_vhd (
const Uint8 *p,
int fd )
119 Uint32 l = p[0] | (p[1] << 8) | (p[2] << 16) | ((p[3] & 0x7F) << 24);
126 if (lseek(fd, filelen, SEEK_SET) != filelen)
131 int r = write(fd, p, l);
144 void sdext_clear_ram(
void)
146 memset(sd_ram_ext, 0xFF,
sizeof sd_ram_ext);
151 static int sdext_detect_rom (
void )
154 Uint8 *p2 = p + 0x2000 - strlen(sdext_rom_signature);
155 if (memcmp(p,
"EXOS_ROM", 8))
157 for (; p < p2; p++ ) {
158 if (!memcmp(p, sdext_rom_signature, strlen(sdext_rom_signature)))
167 static inline off_t _assert_on_csd_size_mismatch ( off_t expected_size,
int expected_mult,
int expected_blocknr,
int expected_blocklen )
169 int mult = 2 ** (i[
"C_SIZE_MULT"] + 2)
170 int blocknr = (i[
"C_SIZE"] + 1) * mult
171 int blocklen = 2 ** i[
"READ_BL_LEN"]
172 off_t
size = (off_t)blocknr * (off_t)blocklen;
173 if (
size != expected_size || mult != expected_mult || blocknr != excepted_blocknr || blocklen != expected_blocklen)
174 FATAL(
"Internal CSD size calculation failure!\nExpected=" PRINTF_LLD " Got=" PRINTF_LLD " (mult=%d blocknr=%d blocklen=%d)",
175 (
long long)expected_size, (
long long)
size,
176 mult, blocknr, blocklen
183 static int _size_calc ( off_t
size )
186 for (blen_i = 9; blen_i < 12; blen_i++) {
188 int blen = 1 << blen_i;
189 for (mult_i = 0; mult_i < 8; mult_i++) {
190 int mult = 1 << (mult_i + 2);
191 int res =
size / blen;
192 if (!(
size % blen) && !(res % mult)) {
193 res = (res / mult) - 1;
194 if (res < 4096 && res > 0) {
198 CSD( 5) = (CSD( 5) & 0xF0) | blen_i;
199 CSD( 6) = (CSD( 6) & 0xFC) | (res >> 10);
200 CSD( 7) = (res >> 2) & 0xFF;
201 CSD( 8) = (CSD( 8) & 0x3F) | ((res & 3) << 6);
202 CSD( 9) = (CSD( 9) & 0xFC) | (mult_i >> 1);
203 CSD(10) = (CSD(10) & 0x7F) | ((mult_i & 1) << 7);
216 static int sdext_check_and_set_size (
void )
220 if (sd_card_size < MIN_CARD_SIZE) {
222 "SD card image file \"%s\" is too small, minimal size is " PRINTF_LLD " Mbytes, but this one is " PRINTF_LLD " bytes long (about " PRINTF_LLD " Mbytes). SD access has been disabled!",
223 sdimg_path, (
long long)(MIN_CARD_SIZE >> 20), (
long long)sd_card_size, (
long long)(sd_card_size >> 20)
229 if (lseek(sdfd, sd_card_size - 512, SEEK_SET) == sd_card_size - 512) {
230 if (read(sdfd, _buffer, 512) == 512) {
232 if (!memcmp(_buffer + 1,
"conectix", 8)) {
235 DEBUG(
"SDEXT: warning, old buggy Microsoft VHD file, activating workaround!" NL);
236 }
else if (!memcmp(_buffer,
"conectix", 8))
239 if (p[60] || p[61] || p[62] || p[63] != 2) {
249 ERROR_WINDOW(
"SD card image \"%s\" I/O error while detecting type: %s.\nSD access has been disabled!",
sdimg_path, strerror(errno));
253 DEBUG(
"SDEXT: VHD file detected as card image." NL);
256 DEBUG(
"SDEXT: VHD file is not detected." NL);
257 if (sd_card_size > MAX_CARD_SIZE) {
259 "SD card image file \"%s\" is too large, maximal allowed size is " PRINTF_LLD " Mbytes, but this one is " PRINTF_LLD " bytes long (about " PRINTF_LLD " Mbytes). "
260 "SD access has been disabled!",
261 sdimg_path, (
long long)(MAX_CARD_SIZE >> 20), (
long long)sd_card_size, (
long long)(sd_card_size >> 20)
265 if ((sd_card_size & 511)) {
266 ERROR_WINDOW(
"SD card image file \"%s\" size is not multiple of 512 bytes! SD access has been disabled!",
sdimg_path);
270 new_size = sd_card_size;
271 while (_size_calc(new_size))
273 if (new_size == sd_card_size)
276 WARNING_WINDOW(
"SD-card image \"%s\" is promoted for extension but it seems to be a VHD file.\nIf you allow extension it WON'T BE USED AS VHD ANY MORE BY OTHER SOFTWARE!",
sdimg_path);
277 INFO_WINDOW(
"SD-card image file \"%s\" is about to be extended with %d bytes (the next valid SD-card size), new size is: " PRINTF_LLD,
sdimg_path, (
int)(new_size - sd_card_size), (
long long)new_size);
278 if (!
QUESTION_WINDOW(
"Not allowed|Allowed (DANGEROUS)",
"Do you allow this extension? NOTE: it's a test feature, do not allow it, if you are unsure!")) {
279 INFO_WINDOW(
"You didn't allow the extension. You can continue, but some EP128 software may fail (ie: fdisk)!");
282 if (lseek(sdfd, new_size - 1, SEEK_SET) != new_size - 1) {
283 ERROR_WINDOW(
"SD card image file \"%s\" cannot be extended (seek error: %s).\nYou can continue but some EP128 software may fail (ie: fdisk)!",
sdimg_path, strerror(errno));
286 if (write(sdfd, sd_rom_ext, 1) != 1) {
287 ERROR_WINDOW(
"SD card image file \"%s\" cannot be extended (write error: %s).\nYou can continue but some EP128 software may fail (ie: fdisk)!",
sdimg_path, strerror(errno));
290 sd_card_size = new_size;
291 INFO_WINDOW(
"Great, image file is successfully extended to valid SD-card size! :-)\nNext time you can enjoy the lack of these info message, as you have valid file size now :-)");
301 void sdext_init (
const char *sdimg_filename,
const char *sdrom_filename )
305 if (
xemu_load_file(sdrom_filename, sd_rom_ext, SDCARD_ROM_SIZE, SDCARD_ROM_SIZE,
"Cannot load SD-card cartridge ROM, SD emulation has been disabled!") < 0) {
306 SD_DEBUG(
"SDEXT: init: REFUSE: no SD-card cartridge ROM code found in loaded ROM set." NL);
309 SD_DEBUG(
"SDEXT: init: cool, SD-card cartridge ROM code seems to be found in loaded ROM set, enabling SD card hardware emulation ..." NL);
317 WARNING_WINDOW(
"SD card image file \"%s\" cannot be open: %s. You can use the emulator but SD card access won't work!",
sdimg_path, strerror(errno));
321 DEBUGPRINT(
"SDEXT: SD image cannot be open in read-write mode, using read-only access (fd=%d)." NL, sdfd);
323 DEBUGPRINT(
"SDEXT: SD image file is open in read/write mode, good (fd=%d)" NL, sdfd);
326 sd_card_size = lseek(sdfd, 0, SEEK_END);
327 if (sdext_check_and_set_size()) {
331 DEBUG(
"SDEXT: SD card size is: " PRINTF_LLD " bytes" NL, (
long long)sd_card_size);
346 SD_DEBUG(
"SDEXT: init end" NL);
360 static void _block_read (
void )
368 ret = read(sdfd, _buffer + 2, 512);
369 SD_DEBUG(
"SDEXT: REGIO: fread retval = %d" NL, ret);
371 _buffer[512 + 2] = 0;
372 _buffer[512 + 3] = 0;
386 static void _spi_shifting_with_sd_card (
void )
399 SD_DEBUG(
"SDEXT: write byte #%d as %02Xh for CMD %d" NL, writing, _write_b, cmd[0]);
401 if (_write_b == 0xFD) {
402 SD_DEBUG(
"SDEXT: Stop token got" NL);
407 if (_write_b != 0xFE && _write_b != 0xFC) {
408 SD_DEBUG(
"SDEXT: Waiting for token ..." NL);
411 SD_DEBUG(
"SDEXT: token found %02Xh" NL, _write_b);
415 _buffer[writing++] = _write_b;
416 if (writing == 512 + 2) {
417 off_t ret, _offset = (cmd[1] << 24) | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
418 _offset += 512UL *
blocks;
420 if (_offset > sd_card_size - 512UL) {
422 SD_DEBUG(
"SDEXT: access beyond the card size!" NL);
424 ret = (lseek(sdfd, _offset, SEEK_SET) == _offset) ? 5 : 13;
426 SD_DEBUG(
"SDEXT: seek error: %s" NL, strerror(errno));
428 ret = (write(sdfd, _buffer, 512) == 512) ? 5 : 13;
430 SD_DEBUG(
"SDEXT: write error: %s" NL, strerror(errno));
434 if (cmd[0] == 24 || ret != 5) {
435 SD_DEBUG(
"SDEXT: cmd-%d end blocks=%d" NL, cmd[0],
blocks);
440 SD_DEBUG(
"SDEXT: cmd-25 end blocks=%d" NL,
blocks);
449 if (cmd_index == 0 && (_write_b & 0xC0) != 0x40) {
450 if (ans_index < ans_size) {
451 SD_DEBUG(
"SDEXT: REGIO: streaming answer byte %d of %d-1 value %02X" NL, ans_index, ans_size, ans_p[ans_index]);
452 _read_b = ans_p[ans_index++];
460 SD_DEBUG(
"SDEXT: REGIO: dummy answer 0xFF" NL);
467 cmd[cmd_index++] = _write_b;
471 SD_DEBUG(
"SDEXT: REGIO: command (CMD%d) received: %02X %02X %02X %02X %02X %02X" NL, cmd[0] & 63, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5]);
486 SD_DEBUG(
"SDEXT: REGIO: command is read CSD register" NL);
487 ADD_ANS(_read_csd_answer);
491 ADD_ANS(_read_cid_answer);
495 ADD_ANS(_read_ocr_answer);
499 ADD_ANS(_stop_transmission_answer);
502 SD_DEBUG(
"SDEXT: REGIO: block counter before CMD12: %d" NL,
blocks);
511 off_t ret, _offset = (cmd[1] << 24) | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
512 SD_DEBUG(
"SDEXT: REGIO: seek to " PRINTF_LLD " in the image file." NL, (
long long)_offset);
514 if (_offset > sd_card_size - 512UL) {
516 SD_DEBUG(
"SDEXT: access beyond the card size!" NL);
519 ret = lseek(sdfd, _offset, SEEK_SET);
520 if (ret != _offset) {
522 SD_DEBUG(
"SDEXT: seek error to " PRINTF_LLD " (got: " PRINTF_LLD ")" NL, (
long long)_offset, (
long long)ret);
526 ans_callback = _block_read;
539 SD_DEBUG(
"SDEXT: REGIO: unimplemented command %d = %02Xh" NL, cmd[0], cmd[0]);
552 SD_DEBUG(
"SDEXT: read cart @ %04X [pc=%04X]" NL,
addr,
Z80_PC);
556 SD_DEBUG(
"SDEXT: reading base ROM, ROM offset = %04X, result = %02X" NL,
addr,
byte);
561 return sd_rom_ext[rom_page_ofs +
addr];
565 SD_DEBUG(
"SDEXT: reading RAM at offset %04X, result = %02X" NL,
addr, sd_ram_ext[
addr]);
566 return sd_ram_ext[
addr];
572 _spi_shifting_with_sd_card();
573 SD_DEBUG(
"SDEXT: REGIO: R: DATA: SPI data register HIGH SPEED read %02X [future byte %02X] [shited out was: %02X]" NL, old, _read_b, _write_b);
579 SD_DEBUG(
"SDEXT: REGIO: R: DATA: SPI data register regular read %02X" NL, _read_b);
582 SD_DEBUG(
"SDEXT: REGIO: R: status" NL);
587 SD_DEBUG(
"SDEXT: REGIO: R: rom pager" NL);
589 return rom_page_ofs >> 8;
591 SD_DEBUG(
"SDEXT: REGIO: R: HS config" NL);
595 FATAL(
"SDEXT: FATAL, unhandled (RD) case");
598 FATAL(
"SDEXT: FATAL, control should not get here");
613 SD_DEBUG(
"SDEXT: writing RAM at offset %04X" NL,
addr);
620 SD_DEBUG(
"SDEXT: REGIO: W: DATA: SPI data register to %02X" NL,
data);
621 if (!is_hs_read) _write_b =
data;
622 _write_specified =
data;
623 _spi_shifting_with_sd_card();
630 SD_DEBUG(
"SDEXT: REGIO: W: control register to %02X CS0=%d CS1=%d" NL,
data, cs0, cs1);
633 rom_page_ofs = (
data & 0xE0) << 8;
634 SD_DEBUG(
"SDEXT: REGIO: W: paging ROM to %02X, eg %04X offset" NL,
data, rom_page_ofs);
637 is_hs_read =
data & 128;
638 _write_b = is_hs_read ? 0xFF : _write_specified;
639 SD_DEBUG(
"SDEXT: REGIO: W: HS read mode is %s" NL, is_hs_read ?
"set" :
"reset");
642 FATAL(
"SDEXT: FATAL, unhandled (WR) case");