36 #ifndef CONFIG_SDEXT_SUPPORT
37 #warning "SDEXT support is disabled by configuration."
40 #define CONFIG_SDEXT_FLASH
43 # define SD_DEBUG DEBUG
45 # define SD_DEBUG(...)
49 static const char *sdext_rom_signature =
"SDEXT";
51 int sdext_cart_enabler = SDEXT_CART_ENABLER_OFF;
53 static int rom_page_ofs;
54 static int is_hs_read;
55 static Uint8 _spi_last_w;
59 static Uint8 sd_ram_ext[7 * 1024];
65 static Uint8 sd_rom_ext[0x10000];
66 static Uint8 *flash[2] = {
memory + 0x10000, sd_rom_ext };
68 static int flash_wr_protect = 0;
69 static int flash_bus_cycle = 0;
70 static int flash_command = 0;
72 static Uint8 cmd[6], cmd_index, _read_b, _write_b, _write_specified;
73 static const Uint8 *ans_p;
74 static int ans_index, ans_size;
76 static int delay_answer;
77 static void (*ans_callback)(void);
80 static Uint8 _buffer[1024];
81 off_t sd_card_size = 0;
83 #define MAX_CARD_SIZE 2147483648UL
84 #define MIN_CARD_SIZE 8388608UL
96 static const Uint8 _stop_transmission_answer[] = {
101 #define CSD(a) _read_csd_answer[(__CSD_OFS) + (a)]
102 static Uint8 _read_csd_answer[] = {
106 0x00, 0x5D, 0x01, 0x32, 0x13, 0x59, 0x80, 0xE3, 0x76, 0xD9, 0xCF, 0xFF, 0x16, 0x40, 0x00, 0x4F,
109 static const Uint8 _read_cid_answer[] = {
113 0x01, 0x50, 0x41, 0x53, 0x30, 0x31, 0x36, 0x42, 0x41, 0x35, 0xE4, 0x39, 0x06, 0x00, 0x35, 0x03,
116 static const Uint8 _read_ocr_answer[] = {
118 0x80, 0xFF, 0x80, 0x00
121 #define ADD_ANS(ans) { ans_p = (ans); ans_index = 0; ans_size = sizeof(ans); }
123 #include "xemu/../rom/ep128/vhd_compressed.c"
127 static int decompress_vhd (
const Uint8 *p,
int fd )
131 Uint32 l = p[0] | (p[1] << 8) | (p[2] << 16) | ((p[3] & 0x7F) << 24);
138 if (lseek(fd, filelen, SEEK_SET) != filelen)
143 int r = write(fd, p, l);
156 void sdext_clear_ram(
void)
158 memset(sd_ram_ext, 0xFF, 0x1C00);
163 static int sdext_detect_rom (
void )
166 Uint8 *p2 = p + 0x2000 - strlen(sdext_rom_signature);
167 if (memcmp(p,
"EXOS_ROM", 8))
169 for (; p < p2; p++ ) {
170 if (!memcmp(p, sdext_rom_signature, strlen(sdext_rom_signature)))
179 static inline off_t _assert_on_csd_size_mismatch ( off_t expected_size,
int expected_mult,
int expected_blocknr,
int expected_blocklen )
181 int mult = 2 ** (i[
"C_SIZE_MULT"] + 2)
182 int blocknr = (i[
"C_SIZE"] + 1) * mult
183 int blocklen = 2 ** i[
"READ_BL_LEN"]
184 off_t
size = (off_t)blocknr * (off_t)blocklen;
185 if (
size != expected_size || mult != expected_mult || blocknr != excepted_blocknr || blocklen != expected_blocklen)
186 FATAL(
"Internal CSD size calculation failure!\nExpected=" PRINTF_LLD " Got=" PRINTF_LLD " (mult=%d blocknr=%d blocklen=%d)",
187 (
long long)expected_size, (
long long)
size,
188 mult, blocknr, blocklen
195 static int _size_calc ( off_t
size )
198 for (blen_i = 9; blen_i < 12; blen_i++) {
200 int blen = 1 << blen_i;
201 for (mult_i = 0; mult_i < 8; mult_i++) {
202 int mult = 1 << (mult_i + 2);
203 int res =
size / blen;
204 if (!(
size % blen) && !(res % mult)) {
205 res = (res / mult) - 1;
206 if (res < 4096 && res > 0) {
210 CSD( 5) = (CSD( 5) & 0xF0) | blen_i;
211 CSD( 6) = (CSD( 6) & 0xFC) | (res >> 10);
212 CSD( 7) = (res >> 2) & 0xFF;
213 CSD( 8) = (CSD( 8) & 0x3F) | ((res & 3) << 6);
214 CSD( 9) = (CSD( 9) & 0xFC) | (mult_i >> 1);
215 CSD(10) = (CSD(10) & 0x7F) | ((mult_i & 1) << 7);
228 static int sdext_check_and_set_size (
void )
232 if (sd_card_size < MIN_CARD_SIZE) {
234 "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!",
235 sdimg_path, (
long long)(MIN_CARD_SIZE >> 20), (
long long)sd_card_size, (
long long)(sd_card_size >> 20)
241 if (lseek(sdfd, sd_card_size - 512, SEEK_SET) == sd_card_size - 512) {
242 if (read(sdfd, _buffer, 512) == 512) {
244 if (!memcmp(_buffer + 1,
"conectix", 8)) {
247 DEBUG(
"SDEXT: warning, old buggy Microsoft VHD file, activating workaround!" NL);
248 }
else if (!memcmp(_buffer,
"conectix", 8))
251 if (p[60] || p[61] || p[62] || p[63] != 2) {
265 DEBUG(
"SDEXT: VHD file detected as card image." NL);
268 DEBUG(
"SDEXT: VHD file is not detected." NL);
269 if (sd_card_size > MAX_CARD_SIZE) {
271 "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). "
272 "SD access has been disabled!",
273 sdimg_path, (
long long)(MAX_CARD_SIZE >> 20), (
long long)sd_card_size, (
long long)(sd_card_size >> 20)
277 if ((sd_card_size & 511)) {
278 ERROR_WINDOW(
"SD card image file \"%s\" size is not multiple of 512 bytes! SD access has been disabled!",
sdimg_path);
282 new_size = sd_card_size;
283 while (_size_calc(new_size))
285 if (new_size == sd_card_size)
288 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);
289 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);
290 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!")) {
291 INFO_WINDOW(
"You didn't allow the extension. You can continue, but some EP128 software may fail (ie: fdisk)!");
294 if (lseek(sdfd, new_size - 1, SEEK_SET) != new_size - 1) {
295 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());
298 if (write(sdfd, sd_rom_ext, 1) != 1) {
299 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());
302 sd_card_size = new_size;
303 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 :-)");
309 void sdext_shutdown (
void )
322 int sdext_init (
const char *img_fn )
326 if (sdext_detect_rom()) {
327 WARNING_WINDOW(
"No SD-card cartridge ROM code found in loaded ROM set. SD card hardware emulation has been disabled!");
329 SD_DEBUG(
"SDEXT: init: REFUSE: no SD-card cartridge ROM code found in loaded ROM set." NL);
332 SD_DEBUG(
"SDEXT: init: cool, SD-card cartridge ROM code seems to be found in loaded ROM set, enabling SD card hardware emulation ..." NL);
341 INFO_WINDOW(
"Warning, SD-card image could be opened only in read-only mode!");
346 int r =
QUESTION_WINDOW(
"?Exit|!Continue without SD card|Create empty image",
"Cannot open default SD card image file.");
357 if (decompress_vhd(empty_vhd_image, sdfd)) {
376 sd_card_size = lseek(sdfd, 0, SEEK_END);
377 if (sdext_check_and_set_size()) {
382 DEBUG(
"SDEXT: SD card size is: " PRINTF_LLD " bytes" NL, (
long long)sd_card_size);
384 memset(sd_rom_ext, 0xFF, 0x10000);
387 memcpy(sd_rom_ext,
memory + 7 * 0x4000, 0x4000);
389 sdext_cart_enabler = SDEXT_CART_ENABLER_ON;
402 SD_DEBUG(
"SDEXT: init end" NL);
412 static void _block_read (
void )
420 ret = read(sdfd, _buffer + 2, 512);
421 SD_DEBUG(
"SDEXT: REGIO: read retval = %d" NL, ret);
423 _buffer[512 + 2] = 0;
424 _buffer[512 + 3] = 0;
438 static void _spi_shifting_with_sd_card ()
451 SD_DEBUG(
"SDEXT: write byte #%d as %02Xh for CMD %d" NL, writing, _write_b, cmd[0]);
453 if (_write_b == 0xFD) {
454 SD_DEBUG(
"SDEXT: Stop token got" NL);
459 if (_write_b != 0xFE && _write_b != 0xFC) {
460 SD_DEBUG(
"SDEXT: Waiting for token ..." NL);
463 SD_DEBUG(
"SDEXT: token found %02Xh" NL, _write_b);
467 _buffer[writing++] = _write_b;
468 if (writing == 512 + 2) {
469 off_t ret, _offset = (cmd[1] << 24) | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
470 _offset += 512UL *
blocks;
472 if (_offset > sd_card_size - 512UL) {
474 SD_DEBUG(
"SDEXT: access beyond the card size!" NL);
476 ret = (lseek(sdfd, _offset, SEEK_SET) == _offset) ? 5 : 13;
478 SD_DEBUG(
"SDEXT: seek error: %s" NL,
ERRSTR());
480 ret = (write(sdfd, _buffer, 512) == 512) ? 5 : 13;
482 SD_DEBUG(
"SDEXT: write error: %s" NL,
ERRSTR());
486 if (cmd[0] == 24 || ret != 5) {
487 SD_DEBUG(
"SDEXT: cmd-%d end blocks=%d" NL, cmd[0],
blocks);
492 SD_DEBUG(
"SDEXT: cmd-25 end blocks=%d" NL,
blocks);
501 if (cmd_index == 0 && (_write_b & 0xC0) != 0x40) {
502 if (ans_index < ans_size) {
503 SD_DEBUG(
"SDEXT: REGIO: streaming answer byte %d of %d-1 value %02X" NL, ans_index, ans_size, ans_p[ans_index]);
504 _read_b = ans_p[ans_index++];
512 SD_DEBUG(
"SDEXT: REGIO: dummy answer 0xFF" NL);
519 cmd[cmd_index++] = _write_b;
523 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]);
538 SD_DEBUG(
"SDEXT: REGIO: command is read CSD register" NL);
539 ADD_ANS(_read_csd_answer);
543 ADD_ANS(_read_cid_answer);
547 ADD_ANS(_read_ocr_answer);
551 ADD_ANS(_stop_transmission_answer);
554 SD_DEBUG(
"SDEXT: REGIO: block counter before CMD12: %d" NL,
blocks);
563 off_t ret, _offset = (cmd[1] << 24) | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
564 SD_DEBUG(
"SDEXT: REGIO: seek to %ld in the image file." NL, _offset);
566 if (_offset > sd_card_size - 512UL) {
568 SD_DEBUG(
"SDEXT: access beyond the card size!" NL);
571 ret = lseek(sdfd, _offset, SEEK_SET);
572 if (ret != _offset) {
574 SD_DEBUG(
"SDEXT: seek error to %ld (got: %ld)" NL, _offset, ret);
578 ans_callback = _block_read;
591 SD_DEBUG(
"SDEXT: REGIO: unimplemented command %d = %02Xh" NL, cmd[0], cmd[0]);
599 static void flash_erase (
int sector )
602 memset(flash[0], 0xFF, 0xC000);
603 SD_DEBUG(
"SDEXT: FLASH: erasing sector 0!" NL);
604 WARNING_WINDOW(
"Erasing flash sector 0! You can safely ignore this warning.");
606 if (abs(sector) == 1) {
607 memset(flash[1], 0xFF, 0x10000);
608 SD_DEBUG(
"SDEXT: FLASH: erasing sector 1!" NL);
609 WARNING_WINDOW(
"Erasing flash sector 1! You can safely ignore this warning.");
618 if (flash_command == 0x90)
619 switch (
addr & 0xFF) {
622 SD_DEBUG(
"SDEXT: FLASH: cmd 0x90 get manufacturer ID, result = %02Xh" NL,
byte);
626 SD_DEBUG(
"SDEXT: FLASH: cmd 0x90 get device ID, result = %02Xh" NL,
byte);
630 SD_DEBUG(
"SDEXT: FLASH: cmd 0x90 get sector protect status, result = %02Xh" NL,
byte);
633 byte = flash[sector][
addr];
634 SD_DEBUG(
"SDEXT: FLASH: cmd 0x90 unknown info requested (%d), accesssing flash content instead." NL,
addr & 0xFF);
638 byte = flash[sector][
addr];
645 static int flash_warn_programming = 1;
648 int idaddr =
addr & 0x3FFF;
649 if (flash_command == 0x90)
651 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);
652 if (flash_wr_protect)
654 switch (flash_bus_cycle) {
659 SD_DEBUG(
"SDEXT: FLASH: erase suspend/resume is not yet supported, ignoring ..." NL);
663 SD_DEBUG(
"SDEXT: FLASH: reset command" NL);
666 if (idaddr != 0xAAA ||
data != 0xAA) {
667 SD_DEBUG(
"SDEXT: FLASH: invalid command sequence at the beginning [bus_cycle=0]" NL);
673 if (idaddr != 0x555 ||
data != 0x55) {
674 SD_DEBUG(
"SDEXT: FLASH: invalid command sequence [bus_cycle=1]" NL);
681 if (idaddr != 0xAAA) {
682 SD_DEBUG(
"SDEXT: FLASH: invalid command sequence [bus_cycle=2]" NL);
687 SD_DEBUG(
"SDEXT: FLASH: unknown command [bus_cycle=2]" NL);
691 flash_command =
data;
695 if (flash_command == 0xA0) {
699 flash[sector][
addr] = newbyte;
700 SD_DEBUG(
"SDEXT: FLASH: programming: sector %d address %04Xh data-req %02Xh, result %02Xh->%02Xh" NL, sector,
addr,
data, oldbyte, newbyte);
701 if (flash_warn_programming) {
702 WARNING_WINDOW(
"Flash programming detected! There will be no further warnings on more bytes.\nYou can safely ignore this warning.");
703 flash_warn_programming = 0;
710 if (idaddr != 0xAAA ||
data != 0xAA) {
711 SD_DEBUG(
"SDEXT: FLASH: invalid command sequence [bus_cycle=3]" NL);
719 if (idaddr != 0x555 ||
data != 0x55) {
720 SD_DEBUG(
"SDEXT: FLASH: invalid command sequence [bus_cycle=4]" NL);
728 if (idaddr == 0xAAA &&
data == 0x10) {
730 }
else if (
data == 0x30) {
737 FATAL(
"Invalid SDEXT FLASH bus cycle #%d on WR", flash_bus_cycle);
749 SD_DEBUG(
"SDEXT: read cart @ %04X [CPU: seg=%02X, pc=%04X]" NL,
addr, ports[0xB0 | (
Z80_PC >> 14)],
Z80_PC);
752 SD_DEBUG(
"SDEXT: reading base ROM, ROM offset = %04X, result = %02X" NL,
addr,
byte);
757 addr = rom_page_ofs + (
addr & 0x1FFF);
758 byte = flash_rd_bus_op(1,
addr);
759 SD_DEBUG(
"SDEXT: reading paged ROM, ROM offset = %04X, result = %02X" NL,
addr,
byte);
764 SD_DEBUG(
"SDEXT: reading RAM at offset %04X, result = %02X" NL,
addr, sd_ram_ext[
addr]);
765 return sd_ram_ext[
addr];
771 _spi_shifting_with_sd_card();
772 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);
778 SD_DEBUG(
"SDEXT: REGIO: R: DATA: SPI data register regular read %02X" NL, _read_b);
781 SD_DEBUG(
"SDEXT: REGIO: R: status" NL);
786 SD_DEBUG(
"SDEXT: REGIO: R: rom pager" NL);
788 return rom_page_ofs >> 8;
790 SD_DEBUG(
"SDEXT: REGIO: R: HS config" NL);
794 FATAL(
"SDEXT: FATAL, unhandled (RD) case");
797 FATAL(
"SDEXT: FATAL, control should not get here");
804 SD_DEBUG(
"SDEXT: write cart @ %04X with %02X [CPU: seg=%02X, pc=%04X]" NL,
addr,
data, ports[0xB0 | (
Z80_PC >> 14)],
Z80_PC);
810 flash_wr_bus_op(1, (
addr & 0x1FFF) + rom_page_ofs,
data);
815 SD_DEBUG(
"SDEXT: writing RAM at offset %04X" NL,
addr);
822 SD_DEBUG(
"SDEXT: REGIO: W: DATA: SPI data register to %02X" NL,
data);
823 if (!is_hs_read) _write_b =
data;
824 _write_specified =
data;
825 _spi_shifting_with_sd_card();
832 SD_DEBUG(
"SDEXT: REGIO: W: control register to %02X CS0=%d CS1=%d" NL,
data, cs0, cs1);
835 rom_page_ofs = (
data & 0xE0) << 8;
836 SD_DEBUG(
"SDEXT: REGIO: W: paging ROM to %02X" NL,
data);
839 is_hs_read =
data & 128;
840 _write_b = is_hs_read ? 0xFF : _write_specified;
841 SD_DEBUG(
"SDEXT: REGIO: W: HS read mode is %s" NL, is_hs_read ?
"set" :
"reset");
844 FATAL(
"SDEXT: FATAL, unhandled (WR) case");