34 #ifndef CONFIG_SDEXT_SUPPORT
35 #warning "SDEXT support is disabled by configuration."
38 #define CONFIG_SDEXT_FLASH
41 # define SD_DEBUG DEBUG
43 # define SD_DEBUG(...)
47 static const char *sdext_rom_signature =
"SDEXT";
49 int sdext_cart_enabler = SDEXT_CART_ENABLER_OFF;
51 static int rom_page_ofs;
52 static int is_hs_read;
53 static Uint8 _spi_last_w;
57 static Uint8 sd_ram_ext[7 * 1024];
63 static Uint8 sd_rom_ext[0x10000];
64 static Uint8 *flash[2] = {
memory + 0x10000, sd_rom_ext };
66 static int flash_wr_protect = 0;
67 static int flash_bus_cycle = 0;
68 static int flash_command = 0;
70 static Uint8 cmd[6], cmd_index, _read_b, _write_b, _write_specified;
71 static const Uint8 *ans_p;
72 static int ans_index, ans_size;
74 static int delay_answer;
75 static void (*ans_callback)(void);
79 static Uint8 _buffer[1024];
80 off_t sd_card_size = 0;
82 #define MAX_CARD_SIZE 2147483648UL
83 #define MIN_CARD_SIZE 8388608UL
95 static const Uint8 _stop_transmission_answer[] = {
100 #define CSD(a) _read_csd_answer[(__CSD_OFS) + (a)]
101 static Uint8 _read_csd_answer[] = {
105 0x00, 0x5D, 0x01, 0x32, 0x13, 0x59, 0x80, 0xE3, 0x76, 0xD9, 0xCF, 0xFF, 0x16, 0x40, 0x00, 0x4F,
108 static const Uint8 _read_cid_answer[] = {
112 0x01, 0x50, 0x41, 0x53, 0x30, 0x31, 0x36, 0x42, 0x41, 0x35, 0xE4, 0x39, 0x06, 0x00, 0x35, 0x03,
115 static const Uint8 _read_ocr_answer[] = {
117 0x80, 0xFF, 0x80, 0x00
120 #define ADD_ANS(ans) { ans_p = (ans); ans_index = 0; ans_size = sizeof(ans); }
122 #include "xemu/../rom/ep128/vhd_compressed.c"
126 static int decompress_vhd (
const Uint8 *p,
int fd )
130 Uint32 l = p[0] | (p[1] << 8) | (p[2] << 16) | ((p[3] & 0x7F) << 24);
137 if (lseek(fd, filelen, SEEK_SET) != filelen)
142 int r = write(fd, p, l);
155 void sdext_clear_ram(
void)
157 memset(sd_ram_ext, 0xFF, 0x1C00);
162 static int sdext_detect_rom (
void )
165 Uint8 *p2 = p + 0x2000 - strlen(sdext_rom_signature);
166 if (memcmp(p,
"EXOS_ROM", 8))
168 for (; p < p2; p++ ) {
169 if (!memcmp(p, sdext_rom_signature, strlen(sdext_rom_signature)))
178 static inline off_t _assert_on_csd_size_mismatch ( off_t expected_size,
int expected_mult,
int expected_blocknr,
int expected_blocklen )
180 int mult = 2 ** (i[
"C_SIZE_MULT"] + 2)
181 int blocknr = (i[
"C_SIZE"] + 1) * mult
182 int blocklen = 2 ** i[
"READ_BL_LEN"]
183 off_t
size = (off_t)blocknr * (off_t)blocklen;
184 if (
size != expected_size || mult != expected_mult || blocknr != excepted_blocknr || blocklen != expected_blocklen)
185 FATAL(
"Internal CSD size calculation failure!\nExpected=" PRINTF_LLD " Got=" PRINTF_LLD " (mult=%d blocknr=%d blocklen=%d)",
186 (
long long)expected_size, (
long long)
size,
187 mult, blocknr, blocklen
194 static int _size_calc ( off_t
size )
197 for (blen_i = 9; blen_i < 12; blen_i++) {
199 int blen = 1 << blen_i;
200 for (mult_i = 0; mult_i < 8; mult_i++) {
201 int mult = 1 << (mult_i + 2);
202 int res =
size / blen;
203 if (!(
size % blen) && !(res % mult)) {
204 res = (res / mult) - 1;
205 if (res < 4096 && res > 0) {
209 CSD( 5) = (CSD( 5) & 0xF0) | blen_i;
210 CSD( 6) = (CSD( 6) & 0xFC) | (res >> 10);
211 CSD( 7) = (res >> 2) & 0xFF;
212 CSD( 8) = (CSD( 8) & 0x3F) | ((res & 3) << 6);
213 CSD( 9) = (CSD( 9) & 0xFC) | (mult_i >> 1);
214 CSD(10) = (CSD(10) & 0x7F) | ((mult_i & 1) << 7);
227 static int sdext_check_and_set_size (
void )
231 if (sd_card_size < MIN_CARD_SIZE) {
233 "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!",
234 sdimg_path, (
long long)(MIN_CARD_SIZE >> 20), (
long long)sd_card_size, (
long long)(sd_card_size >> 20)
240 if (lseek(sdfd, sd_card_size - 512, SEEK_SET) == sd_card_size - 512) {
241 if (read(sdfd, _buffer, 512) == 512) {
243 if (!memcmp(_buffer + 1,
"conectix", 8)) {
246 DEBUG(
"SDEXT: warning, old buggy Microsoft VHD file, activating workaround!" NL);
247 }
else if (!memcmp(_buffer,
"conectix", 8))
250 if (p[60] || p[61] || p[62] || p[63] != 2) {
264 DEBUG(
"SDEXT: VHD file detected as card image." NL);
267 DEBUG(
"SDEXT: VHD file is not detected." NL);
268 if (sd_card_size > MAX_CARD_SIZE) {
270 "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). "
271 "SD access has been disabled!",
272 sdimg_path, (
long long)(MAX_CARD_SIZE >> 20), (
long long)sd_card_size, (
long long)(sd_card_size >> 20)
276 if ((sd_card_size & 511)) {
277 ERROR_WINDOW(
"SD card image file \"%s\" size is not multiple of 512 bytes! SD access has been disabled!",
sdimg_path);
281 new_size = sd_card_size;
282 while (_size_calc(new_size))
284 if (new_size == sd_card_size)
287 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);
288 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);
289 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!")) {
290 INFO_WINDOW(
"You didn't allow the extension. You can continue, but some EP128 software may fail (ie: fdisk)!");
293 if (lseek(sdfd, new_size - 1, SEEK_SET) != new_size - 1) {
294 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,
ERRSTR());
297 if (write(sdfd, sd_rom_ext, 1) != 1) {
298 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,
ERRSTR());
301 sd_card_size = new_size;
302 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 :-)");
312 void sdext_init (
void )
315 if (sdext_detect_rom()) {
316 WARNING_WINDOW(
"No SD-card cartridge ROM code found in loaded ROM set. SD card hardware emulation has been disabled!");
319 SD_DEBUG(
"SDEXT: init: REFUSE: no SD-card cartridge ROM code found in loaded ROM set." NL);
322 SD_DEBUG(
"SDEXT: init: cool, SD-card cartridge ROM code seems to be found in loaded ROM set, enabling SD card hardware emulation ..." NL);
330 DEBUGPRINT(
"SDEXT: SD image file is re-open in read/write mode, good (fd=%d)." NL, fileno(sdf));
333 DEBUGPRINT(
"SDEXT: SD image cannot be re-open in read-write mode, using read-only access (fd=%d)." NL, fileno(sdf));
337 if (!sdf && !strcmp(config_getopt_str(
"sdimg"),
SDCARD_IMG_FN)) {
338 int r =
QUESTION_WINDOW(
"?Exit|!Continue without SD card|Create empty image",
"Cannot open default SD card image file.");
342 char pathbuffer[PATH_MAX + 1];
347 goto try_to_open_image;
349 r = decompress_vhd(empty_vhd_image, fileno(sdf));
354 goto try_to_open_image;
357 pathbuffer[strlen(pathbuffer) - 4] = 0;
361 INFO_WINDOW(
"Empty image file has been created: %s", pathbuffer);
362 goto try_to_open_image;
370 sd_card_size = lseek(sdfd, 0, SEEK_END);
371 if (sdext_check_and_set_size()) {
376 DEBUG(
"SDEXT: SD card size is: " PRINTF_LLD " bytes" NL, (
long long)sd_card_size);
378 memset(sd_rom_ext, 0xFF, 0x10000);
381 memcpy(sd_rom_ext,
memory + 7 * 0x4000, 0x4000);
383 sdext_cart_enabler = SDEXT_CART_ENABLER_ON;
396 SD_DEBUG(
"SDEXT: init end" NL);
405 static void _block_read (
void )
413 ret = read(sdfd, _buffer + 2, 512);
414 SD_DEBUG(
"SDEXT: REGIO: fread retval = %d" NL, ret);
416 _buffer[512 + 2] = 0;
417 _buffer[512 + 3] = 0;
431 static void _spi_shifting_with_sd_card ()
444 SD_DEBUG(
"SDEXT: write byte #%d as %02Xh for CMD %d" NL, writing, _write_b, cmd[0]);
446 if (_write_b == 0xFD) {
447 SD_DEBUG(
"SDEXT: Stop token got" NL);
452 if (_write_b != 0xFE && _write_b != 0xFC) {
453 SD_DEBUG(
"SDEXT: Waiting for token ..." NL);
456 SD_DEBUG(
"SDEXT: token found %02Xh" NL, _write_b);
460 _buffer[writing++] = _write_b;
461 if (writing == 512 + 2) {
462 off_t ret, _offset = (cmd[1] << 24) | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
463 _offset += 512UL *
blocks;
465 if (_offset > sd_card_size - 512UL) {
467 SD_DEBUG(
"SDEXT: access beyond the card size!" NL);
469 ret = (lseek(sdfd, _offset, SEEK_SET) == _offset) ? 5 : 13;
471 SD_DEBUG(
"SDEXT: seek error: %s" NL,
ERRSTR());
473 ret = (write(sdfd, _buffer, 512) == 512) ? 5 : 13;
475 SD_DEBUG(
"SDEXT: write error: %s" NL,
ERRSTR());
479 if (cmd[0] == 24 || ret != 5) {
480 SD_DEBUG(
"SDEXT: cmd-%d end blocks=%d" NL, cmd[0],
blocks);
485 SD_DEBUG(
"SDEXT: cmd-25 end blocks=%d" NL,
blocks);
494 if (cmd_index == 0 && (_write_b & 0xC0) != 0x40) {
495 if (ans_index < ans_size) {
496 SD_DEBUG(
"SDEXT: REGIO: streaming answer byte %d of %d-1 value %02X" NL, ans_index, ans_size, ans_p[ans_index]);
497 _read_b = ans_p[ans_index++];
505 SD_DEBUG(
"SDEXT: REGIO: dummy answer 0xFF" NL);
512 cmd[cmd_index++] = _write_b;
516 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]);
531 SD_DEBUG(
"SDEXT: REGIO: command is read CSD register" NL);
532 ADD_ANS(_read_csd_answer);
536 ADD_ANS(_read_cid_answer);
540 ADD_ANS(_read_ocr_answer);
544 ADD_ANS(_stop_transmission_answer);
547 SD_DEBUG(
"SDEXT: REGIO: block counter before CMD12: %d" NL,
blocks);
556 off_t ret, _offset = (cmd[1] << 24) | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
557 SD_DEBUG(
"SDEXT: REGIO: seek to %ld in the image file." NL, _offset);
559 if (_offset > sd_card_size - 512UL) {
561 SD_DEBUG(
"SDEXT: access beyond the card size!" NL);
564 ret = lseek(sdfd, _offset, SEEK_SET);
565 if (ret != _offset) {
567 SD_DEBUG(
"SDEXT: seek error to %ld (got: %ld)" NL, _offset, ret);
571 ans_callback = _block_read;
584 SD_DEBUG(
"SDEXT: REGIO: unimplemented command %d = %02Xh" NL, cmd[0], cmd[0]);
592 static void flash_erase (
int sector )
595 memset(flash[0], 0xFF, 0xC000);
596 SD_DEBUG(
"SDEXT: FLASH: erasing sector 0!" NL);
597 WARNING_WINDOW(
"Erasing flash sector 0! You can safely ignore this warning.");
599 if (abs(sector) == 1) {
600 memset(flash[1], 0xFF, 0x10000);
601 SD_DEBUG(
"SDEXT: FLASH: erasing sector 1!" NL);
602 WARNING_WINDOW(
"Erasing flash sector 1! You can safely ignore this warning.");
611 if (flash_command == 0x90)
612 switch (
addr & 0xFF) {
615 SD_DEBUG(
"SDEXT: FLASH: cmd 0x90 get manufacturer ID, result = %02Xh" NL,
byte);
619 SD_DEBUG(
"SDEXT: FLASH: cmd 0x90 get device ID, result = %02Xh" NL,
byte);
623 SD_DEBUG(
"SDEXT: FLASH: cmd 0x90 get sector protect status, result = %02Xh" NL,
byte);
626 byte = flash[sector][
addr];
627 SD_DEBUG(
"SDEXT: FLASH: cmd 0x90 unknown info requested (%d), accesssing flash content instead." NL,
addr & 0xFF);
631 byte = flash[sector][
addr];
638 static int flash_warn_programming = 1;
641 int idaddr =
addr & 0x3FFF;
642 if (flash_command == 0x90)
644 SD_DEBUG(
"SDEXT: FLASH: WR OP: sector %d addr %04Xh data %02Xh flash-bus-cycle %d flash-command %02Xh" NL, sector,
addr,
data, flash_bus_cycle, flash_command);
645 if (flash_wr_protect)
647 switch (flash_bus_cycle) {
652 SD_DEBUG(
"SDEXT: FLASH: erase suspend/resume is not yet supported, ignoring ..." NL);
656 SD_DEBUG(
"SDEXT: FLASH: reset command" NL);
659 if (idaddr != 0xAAA ||
data != 0xAA) {
660 SD_DEBUG(
"SDEXT: FLASH: invalid command sequence at the beginning [bus_cycle=0]" NL);
666 if (idaddr != 0x555 ||
data != 0x55) {
667 SD_DEBUG(
"SDEXT: FLASH: invalid command sequence [bus_cycle=1]" NL);
674 if (idaddr != 0xAAA) {
675 SD_DEBUG(
"SDEXT: FLASH: invalid command sequence [bus_cycle=2]" NL);
680 SD_DEBUG(
"SDEXT: FLASH: unknown command [bus_cycle=2]" NL);
684 flash_command =
data;
688 if (flash_command == 0xA0) {
692 flash[sector][
addr] = newbyte;
693 SD_DEBUG(
"SDEXT: FLASH: programming: sector %d address %04Xh data-req %02Xh, result %02Xh->%02Xh" NL, sector,
addr,
data, oldbyte, newbyte);
694 if (flash_warn_programming) {
695 WARNING_WINDOW(
"Flash programming detected! There will be no further warnings on more bytes.\nYou can safely ignore this warning.");
696 flash_warn_programming = 0;
703 if (idaddr != 0xAAA ||
data != 0xAA) {
704 SD_DEBUG(
"SDEXT: FLASH: invalid command sequence [bus_cycle=3]" NL);
712 if (idaddr != 0x555 ||
data != 0x55) {
713 SD_DEBUG(
"SDEXT: FLASH: invalid command sequence [bus_cycle=4]" NL);
721 if (idaddr == 0xAAA &&
data == 0x10) {
723 }
else if (
data == 0x30) {
730 FATAL(
"Invalid SDEXT FLASH bus cycle #%d on WR", flash_bus_cycle);
742 SD_DEBUG(
"SDEXT: read cart @ %04X [CPU: seg=%02X, pc=%04X]" NL,
addr, ports[0xB0 | (
Z80_PC >> 14)],
Z80_PC);
745 SD_DEBUG(
"SDEXT: reading base ROM, ROM offset = %04X, result = %02X" NL,
addr,
byte);
750 addr = rom_page_ofs + (
addr & 0x1FFF);
751 byte = flash_rd_bus_op(1,
addr);
752 SD_DEBUG(
"SDEXT: reading paged ROM, ROM offset = %04X, result = %02X" NL,
addr,
byte);
757 SD_DEBUG(
"SDEXT: reading RAM at offset %04X, result = %02X" NL,
addr, sd_ram_ext[
addr]);
758 return sd_ram_ext[
addr];
764 _spi_shifting_with_sd_card();
765 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);
771 SD_DEBUG(
"SDEXT: REGIO: R: DATA: SPI data register regular read %02X" NL, _read_b);
774 SD_DEBUG(
"SDEXT: REGIO: R: status" NL);
779 SD_DEBUG(
"SDEXT: REGIO: R: rom pager" NL);
781 return rom_page_ofs >> 8;
783 SD_DEBUG(
"SDEXT: REGIO: R: HS config" NL);
787 FATAL(
"SDEXT: FATAL, unhandled (RD) case");
790 FATAL(
"SDEXT: FATAL, control should not get here");
797 SD_DEBUG(
"SDEXT: write cart @ %04X with %02X [CPU: seg=%02X, pc=%04X]" NL,
addr,
data, ports[0xB0 | (
Z80_PC >> 14)],
Z80_PC);
803 flash_wr_bus_op(1, (
addr & 0x1FFF) + rom_page_ofs,
data);
808 SD_DEBUG(
"SDEXT: writing RAM at offset %04X" NL,
addr);
815 SD_DEBUG(
"SDEXT: REGIO: W: DATA: SPI data register to %02X" NL,
data);
816 if (!is_hs_read) _write_b =
data;
817 _write_specified =
data;
818 _spi_shifting_with_sd_card();
825 SD_DEBUG(
"SDEXT: REGIO: W: control register to %02X CS0=%d CS1=%d" NL,
data, cs0, cs1);
828 rom_page_ofs = (
data & 0xE0) << 8;
829 SD_DEBUG(
"SDEXT: REGIO: W: paging ROM to %02X" NL,
data);
832 is_hs_read =
data & 128;
833 _write_b = is_hs_read ? 0xFF : _write_specified;
834 SD_DEBUG(
"SDEXT: REGIO: W: HS read mode is %s" NL, is_hs_read ?
"set" :
"reset");
837 FATAL(
"SDEXT: FATAL, unhandled (WR) case");