Xemu [doxygen]  hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
sdext.c
Go to the documentation of this file.
1 /* Minimalistic Enterprise-128 emulator with focus on "exotic" hardware
2  Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
3  Copyright (C)2015-2016,2020-2022 LGB (Gábor Lénárt) <lgblgblgb@gmail.com>
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18 
19 /* General SD information:
20  http://elm-chan.org/docs/mmc/mmc_e.html
21  http://www.mikroe.com/downloads/get/1624/microsd_card_spec.pdf
22  http://users.ece.utexas.edu/~valvano/EE345M/SD_Physical_Layer_Spec.pdf
23  Flash IC used (AM29F400BT) on the cartridge:
24  http://www.mouser.com/ds/2/380/spansion%20inc_am29f400b_eol_21505e8-329620.pdf
25 */
26 
27 #include "xemu/emutools.h"
28 #include "xemu/emutools_files.h"
29 #include "enterprise128.h"
30 #include "sdext.h"
31 #include "cpu.h"
32 #include <unistd.h>
33 #include <errno.h>
34 #include <fcntl.h>
35 
36 #ifndef CONFIG_SDEXT_SUPPORT
37 #warning "SDEXT support is disabled by configuration."
38 #else
39 //#define DEBUG_SDEXT
40 #define CONFIG_SDEXT_FLASH
41 
42 #ifdef DEBUG_SDEXT
43 # define SD_DEBUG DEBUG
44 #else
45 # define SD_DEBUG(...)
46 #endif
47 
48 
49 static const char *sdext_rom_signature = "SDEXT";
50 
51 int sdext_cart_enabler = SDEXT_CART_ENABLER_OFF;
52 char sdimg_path[PATH_MAX + 1];
53 static int rom_page_ofs;
54 static int is_hs_read;
55 static Uint8 _spi_last_w;
56 static int cs0, cs1;
57 static Uint8 status;
58 
59 static Uint8 sd_ram_ext[7 * 1024]; // 7K of accessible SRAM
60 /* The FIRST 64K of flash (sector 0) is structured this way:
61  * first 48K is accessed directly at segment 4,5,6, so it's part of the normal EP memory emulated
62  * the last 16K is CANNOT BE accessed at all from EP
63  It's part of the main memory array at the given offset, see flash[0][addr] below
64  The SECOND 64K of flash (sector 1) is stored in sd_rom_ext (see below), it's flash[1][addr] */
65 static Uint8 sd_rom_ext[0x10000];
66 static Uint8 *flash[2] = { memory + 0x10000, sd_rom_ext };
67 
68 static int flash_wr_protect = 0;
69 static int flash_bus_cycle = 0;
70 static int flash_command = 0;
71 
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;
75 static int writing;
76 static int delay_answer;
77 static void (*ans_callback)(void);
78 
79 static int sdfd = -1;
80 static Uint8 _buffer[1024];
81 off_t sd_card_size = 0;
82 
83 #define MAX_CARD_SIZE 2147483648UL
84 #define MIN_CARD_SIZE 8388608UL
85 
86 /* ID files:
87  * C0 71 00 00 │ 00 5D 01 32 │ 13 59 80 E3 │ 76 D9 CF FF │ 16 40 00 4F │ 01 50 41 53
88  * 30 31 36 42 │ 41 35 E4 39 │ 06 00 35 03 │ 80 FF 80 00 │ 00 00 00 00 │ 00 00 00 00
89  * 4 bytes: size in sectors: C0 71 00 00
90  * CSD register 00 5D 01 32 │ 13 59 80 E3 │ 76 D9 CF FF │ 16 40 00 4F
91  * CID register 01 50 41 53 | 30 31 36 42 │ 41 35 E4 39 │ 06 00 35 03
92  * OCR register 80 FF 80 00
93  */
94 
95 
96 static const Uint8 _stop_transmission_answer[] = {
97  0, 0, 0, 0, // "stuff byte" and some of it is the R1 answer anyway
98  0xFF // SD card is ready again
99 };
100 #define __CSD_OFS 2
101 #define CSD(a) _read_csd_answer[(__CSD_OFS) + (a)]
102 static Uint8 _read_csd_answer[] = {
103  0xFF, // waiting a bit
104  0xFE, // data token
105  // the CSD itself
106  0x00, 0x5D, 0x01, 0x32, 0x13, 0x59, 0x80, 0xE3, 0x76, 0xD9, 0xCF, 0xFF, 0x16, 0x40, 0x00, 0x4F,
107  0, 0 // CRC bytes
108 };
109 static const Uint8 _read_cid_answer[] = {
110  0xFF, // waiting a bit
111  0xFE, // data token
112  // the CID itself
113  0x01, 0x50, 0x41, 0x53, 0x30, 0x31, 0x36, 0x42, 0x41, 0x35, 0xE4, 0x39, 0x06, 0x00, 0x35, 0x03,
114  0, 0 // CRC bytes
115 };
116 static const Uint8 _read_ocr_answer[] = { // no data token, nor CRC! (technically this is the R3 answer minus the R1 part at the beginning ...)
117  // the OCR itself
118  0x80, 0xFF, 0x80, 0x00
119 };
120 
121 #define ADD_ANS(ans) { ans_p = (ans); ans_index = 0; ans_size = sizeof(ans); }
122 
123 #include "xemu/../rom/ep128/vhd_compressed.c"
124 
125 
126 
127 static int decompress_vhd ( const Uint8 *p, int fd )
128 {
129  int filelen = 0;
130  for (;;) {
131  Uint32 l = p[0] | (p[1] << 8) | (p[2] << 16) | ((p[3] & 0x7F) << 24);
132  if (!l)
133  break;
134  p += 4;
135  filelen += l;
136  if (p[-1] & 0x80) {
137  // printf("Zero seq len = %d\n", l);
138  if (lseek(fd, filelen, SEEK_SET) != filelen)
139  return 1;
140  } else {
141  // printf("Data len = %d\n", l);
142  while (l) {
143  int r = write(fd, p, l);
144  if (r <= 0)
145  return 1;
146  l -= r;
147  p += r;
148  }
149  }
150  }
151  return 0;
152 }
153 
154 
155 
156 void sdext_clear_ram(void)
157 {
158  memset(sd_ram_ext, 0xFF, 0x1C00);
159 }
160 
161 
162 
163 static int sdext_detect_rom ( void )
164 {
165  Uint8 *p = memory + 7 * 0x4000;
166  Uint8 *p2 = p + 0x2000 - strlen(sdext_rom_signature);
167  if (memcmp(p, "EXOS_ROM", 8))
168  return 1; // No EXOS_ROM header
169  for (; p < p2; p++ ) {
170  if (!memcmp(p, sdext_rom_signature, strlen(sdext_rom_signature)))
171  return 0; // found our extra ID
172  }
173  return 1; // our ID cannot be found
174 }
175 
176 
177 
178 #if 0
179 static inline off_t _assert_on_csd_size_mismatch ( off_t expected_size, int expected_mult, int expected_blocknr, int expected_blocklen )
180 {
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
189  );
190 }
191 #endif
192 
193 
194 
195 static int _size_calc ( off_t size )
196 {
197  int blen_i;
198  for (blen_i = 9; blen_i < 12; blen_i++) {
199  int mult_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) {
207  //printf("MAY HIT with blen=%d[%d],mult=%d[%d],result=%d\n",
208  // blen, blen_i, mult, mult_i, res
209  //);
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);
216  // CHECKING the result follows now!
217  //_assert_on_csd_size_mismatch(size, mult, res, blen);
218  return 0;
219  }
220  }
221  }
222  }
223  return 1;
224 }
225 
226 
227 
228 static int sdext_check_and_set_size ( void )
229 {
230  off_t new_size;
231  int is_vhd;
232  if (sd_card_size < MIN_CARD_SIZE) {
233  ERROR_WINDOW(
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)
236  );
237  return 1;
238  }
239  /* check for VHD footer (not the real part of the image, +512 bytes structure at the end) */
240  is_vhd = -1;
241  if (lseek(sdfd, sd_card_size - 512, SEEK_SET) == sd_card_size - 512) {
242  if (read(sdfd, _buffer, 512) == 512) {
243  Uint8 *p = NULL;
244  if (!memcmp(_buffer + 1, "conectix", 8)) {
245  sd_card_size++; // old, buggy Microsoft tool maybe, 511 bytes footer instead of 512. Treating size as the normalized one
246  p = _buffer + 1;
247  DEBUG("SDEXT: warning, old buggy Microsoft VHD file, activating workaround!" NL);
248  } else if (!memcmp(_buffer, "conectix", 8))
249  p = _buffer;
250  if (p) {
251  if (p[60] || p[61] || p[62] || p[63] != 2) {
252  ERROR_WINDOW("SD card image \"%s\" is an unsupported VHD file (not fixed, maybe dynamic?)", sdimg_path);
253  return 1;
254  }
255  is_vhd = 1;
256  } else
257  is_vhd = 0;
258  }
259  }
260  if (is_vhd < 0) {
261  ERROR_WINDOW("SD card image \"%s\" I/O error while detecting type: %s.\nSD access has been disabled!", sdimg_path, ERRSTR());
262  return 1;
263  }
264  if (is_vhd) {
265  DEBUG("SDEXT: VHD file detected as card image." NL);
266  sd_card_size -= 512;
267  } else
268  DEBUG("SDEXT: VHD file is not detected." NL);
269  if (sd_card_size > MAX_CARD_SIZE) { // do this check here, as VHD footer could overflow on 2G boundary at the beginning what we have support for in Xep128
270  ERROR_WINDOW(
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)
274  );
275  return 1;
276  }
277  if ((sd_card_size & 511)) { // do this check here, as buggy MS tool can create 511 "tail" as footer
278  ERROR_WINDOW("SD card image file \"%s\" size is not multiple of 512 bytes! SD access has been disabled!", sdimg_path);
279  return 1;
280  }
281  /* probing size, optionally extending on request */
282  new_size = sd_card_size;
283  while (_size_calc(new_size))
284  new_size += 512;
285  if (new_size == sd_card_size)
286  return 0;
287  if (is_vhd)
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)!");
292  return 0;
293  }
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());
296  return 0;
297  }
298  if (write(sdfd, sd_rom_ext, 1) != 1) { // sd_rom_ext is just used to write some *RANDOM* byte, the content is not so important here :-P It will create a file "with hole" btw.
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());
300  return 0;
301  }
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 :-)");
304  return 0;
305 }
306 
307 
308 
309 void sdext_shutdown ( void )
310 {
311  if (sdfd >= 0) {
312  close(sdfd);
313  sdfd = -1;
314  }
315 }
316 
317 
318 /* SDEXT emulation currently excepts the cartridge area (segments 4-7) to be filled
319  * with the FLASH ROM content. Even segment 7, which will be copied to the second 64K "hidden"
320  * and pagable flash area of the SD cartridge. Currently, there is no support for the full
321  * sized SDEXT flash image */
322 int sdext_init ( const char *img_fn )
323 {
324  sdext_shutdown();
325  /* try to detect SDEXT ROM extension and only turn on emulation if it exists */
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!");
328  *sdimg_path = 0;
329  SD_DEBUG("SDEXT: init: REFUSE: no SD-card cartridge ROM code found in loaded ROM set." NL);
330  return 0;
331  }
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);
333  // try to open SD card image. If not found, and it's the DEFAULT config option we provide user to install an empty one (and later to download a populated one)
334  for (;;) {
335  int ro = O_RDONLY;
336  sdfd = xemu_open_file(img_fn, O_RDWR, &ro, sdimg_path);
338  if (sdfd >= 0) {
339  DEBUGPRINT("SDEXT: SD-card image is open %s from file %s" NL, sdimg_path, ro ? "R/O" : "R/W");
340  if (ro)
341  INFO_WINDOW("Warning, SD-card image could be opened only in read-only mode!");
342  break;
343  } else {
344  if (!strcmp(img_fn, SDCARD_IMG_FN)) {
345  // if this was the default image, then we may want to give some help to the user to create it!
346  int r = QUESTION_WINDOW("?Exit|!Continue without SD card|Create empty image", "Cannot open default SD card image file.");
347  if (r == 1)
348  break;
349  if (r == 0)
350  XEMUEXIT(0);
351  if (r == 2) { // create an empty image
352  sdfd = xemu_open_file(img_fn, O_CREAT | O_TRUNC | O_RDWR, NULL, sdimg_path);
353  if (sdfd < 0) {
354  ERROR_WINDOW("Cannot create empty image: %s", ERRSTR());
355  continue;
356  }
357  if (decompress_vhd(empty_vhd_image, sdfd)) {
358  ERROR_WINDOW("Error decompressing empty image: %s", ERRSTR());
359  close(sdfd);
360  sdfd = -1;
361  unlink(sdimg_path);
362  continue;
363  }
364  break;
365  }
366  } else {
367  ERROR_WINDOW("Could not open requested SD-card image: %s\n%s", ERRSTR(), img_fn);
368  XEMUEXIT(0);
369  }
370  }
371  }
372  if (sdfd < 0) {
373  WARNING_WINDOW("SD card image file \"%s\" cannot be open: %s. You can use Xep128 but SD card access won't work!", sdimg_path, ERRSTR());
374  *sdimg_path = 0;
375  } else {
376  sd_card_size = lseek(sdfd, 0, SEEK_END);
377  if (sdext_check_and_set_size()) {
378  close(sdfd);
379  sdfd = -1;
380  *sdimg_path = 0;
381  } else
382  DEBUG("SDEXT: SD card size is: " PRINTF_LLD " bytes" NL, (long long)sd_card_size);
383  }
384  memset(sd_rom_ext, 0xFF, 0x10000);
385  /* Copy ROM image of 16K to the second 64K of the cartridge flash. Currently only 8K is used.
386  It's possible to use 64K the ROM set image used by Xep128 can only hold 16K this way, though. */
387  memcpy(sd_rom_ext, memory + 7 * 0x4000, 0x4000);
388  sdext_clear_ram();
389  sdext_cart_enabler = SDEXT_CART_ENABLER_ON; // turn emulation on
390  rom_page_ofs = 0;
391  is_hs_read = 0;
392  cmd_index = 0;
393  ans_size = 0;
394  delay_answer = 0;
395  ans_index = 0;
396  ans_callback = NULL;
397  status = 0;
398  _read_b = 0;
399  _write_b = 0xFF;
400  _spi_last_w = 0xFF;
401  writing = -2;
402  SD_DEBUG("SDEXT: init end" NL);
403  return 0;
404 }
405 
406 
407 static int blocks;
408 
409 
410 // FIXME: error handling of read() !!!!
411 // FIXME: check excess of card size (during multiple block read) !!!!
412 static void _block_read ( void )
413 {
414  int ret;
415  z80ex_w_states(40); // TODO: fake some wait states here, actully this is the WRONG method, as not the Z80 should wait but the SD card's answer ...
416  blocks++;
417  _buffer[0] = 0xFF; // wait a bit
418  _buffer[1] = 0xFE; // data token
419  //ret = fread(_buffer + 2, 1, 512, sdf);
420  ret = read(sdfd, _buffer + 2, 512);
421  SD_DEBUG("SDEXT: REGIO: read retval = %d" NL, ret);
422  (void)ret;
423  _buffer[512 + 2] = 0; // CRC
424  _buffer[512 + 3] = 0; // CRC
425  ans_p = _buffer;
426  ans_index = 0;
427  ans_size = 512 + 4;
428 }
429 
430 
431 
432 /* SPI is a read/write in once stuff. We have only a single function ...
433  * _write_b is the data value to put on MOSI
434  * _read_b is the data read from MISO without spending _ANY_ SPI time to do shifting!
435  * This is not a real thing, but easier to code this way.
436  * The implementation of the real behaviour is up to the caller of this function.
437  */
438 static void _spi_shifting_with_sd_card ()
439 {
440  if (!cs0) { // Currently, we only emulate one SD card, and it must be selected for any answer
441  _read_b = 0xFF;
442  return;
443  }
444  /* begin of write support */
445  if (delay_answer) {
446  delay_answer = 0;
447  return;
448  }
449  if (writing > -2) {
450  _read_b = 0xFF;
451  SD_DEBUG("SDEXT: write byte #%d as %02Xh for CMD %d" NL, writing, _write_b, cmd[0]);
452  if (writing == -1) {
453  if (_write_b == 0xFD) { // stop token
454  SD_DEBUG("SDEXT: Stop token got" NL);
455  _read_b = 0; // wait a tiny time ...
456  writing = -2; // ... but otherwise, end of write session
457  return;
458  }
459  if (_write_b != 0xFE && _write_b != 0xFC) {
460  SD_DEBUG("SDEXT: Waiting for token ..." NL);
461  return;
462  }
463  SD_DEBUG("SDEXT: token found %02Xh" NL, _write_b);
464  writing = 0;
465  return;
466  }
467  _buffer[writing++] = _write_b; // store written byte
468  if (writing == 512 + 2) { // if one block (+ 2byte CRC) is written by host ...
469  off_t ret, _offset = (cmd[1] << 24) | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
470  _offset += 512UL * blocks;
471  blocks++;
472  if (_offset > sd_card_size - 512UL) {
473  ret = 13;
474  SD_DEBUG("SDEXT: access beyond the card size!" NL);
475  } else {
476  ret = (lseek(sdfd, _offset, SEEK_SET) == _offset) ? 5 : 13;
477  if (ret != 5)
478  SD_DEBUG("SDEXT: seek error: %s" NL, ERRSTR());
479  else {
480  ret = (write(sdfd, _buffer, 512) == 512) ? 5 : 13;
481  if (ret != 5)
482  SD_DEBUG("SDEXT: write error: %s" NL, ERRSTR());
483  }
484  }
485  // space for the actual block write ...
486  if (cmd[0] == 24 || ret != 5) {
487  SD_DEBUG("SDEXT: cmd-%d end blocks=%d" NL, cmd[0], blocks);
488  _read_b = ret; // data accepted?
489  writing = -2; // turn off write mode
490  delay_answer = 1;
491  } else {
492  SD_DEBUG("SDEXT: cmd-25 end blocks=%d" NL, blocks);
493  _read_b = ret; // data accepted?
494  writing = -1; // write mode back to the token waiting phase
495  delay_answer = 1;
496  }
497  }
498  return;
499  }
500  /* end of write support */
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++];
505  } else {
506  if (ans_callback)
507  ans_callback();
508  else {
509  //_read_b = 0xFF;
510  ans_index = 0;
511  ans_size = 0;
512  SD_DEBUG("SDEXT: REGIO: dummy answer 0xFF" NL);
513  }
514  _read_b = 0xFF;
515  }
516  return;
517  }
518  if (cmd_index < 6) {
519  cmd[cmd_index++] = _write_b;
520  _read_b = 0xFF;
521  return;
522  }
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]);
524  cmd[0] &= 63;
525  cmd_index = 0;
526  ans_callback = NULL;
527  switch (cmd[0]) {
528  case 0: // CMD 0
529  _read_b = 1; // IDLE state R1 answer
530  break;
531  case 1: // CMD 1 - init
532  _read_b = 0; // non-IDLE now (?) R1 answer
533  break;
534  case 16: // CMD16 - set blocklen (?!) : we only handles that as dummy command oh-oh ...
535  _read_b = 0; // R1 answer
536  break;
537  case 9: // CMD9: read CSD register
538  SD_DEBUG("SDEXT: REGIO: command is read CSD register" NL);
539  ADD_ANS(_read_csd_answer);
540  _read_b = 0; // R1
541  break;
542  case 10: // CMD10: read CID register
543  ADD_ANS(_read_cid_answer);
544  _read_b = 0; // R1
545  break;
546  case 58: // CMD58: read OCR
547  ADD_ANS(_read_ocr_answer);
548  _read_b = 0; // R1 (R3 is sent as data in the emulation without the data token)
549  break;
550  case 12: // CMD12: stop transmission (reading multiple)
551  ADD_ANS(_stop_transmission_answer);
552  _read_b = 0;
553  // actually we don't do too much, as on receiving a new command callback will be deleted before this switch-case block
554  SD_DEBUG("SDEXT: REGIO: block counter before CMD12: %d" NL, blocks);
555  blocks = 0;
556  break;
557  case 17: // CMD17: read a single block, babe
558  case 18: // CMD18: read multiple blocks
559  blocks = 0;
560  if (sdfd < 0)
561  _read_b = 32; // address error, if no SD card image ... [this is bad TODO, better error handling]
562  else {
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);
565  z80ex_w_states(100); // TODO: fake some wait states here, actully this is the WRONG method, as not the Z80 should wait but the SD card's answer ...
566  if (_offset > sd_card_size - 512UL) {
567  _read_b = 32; // address error, TODO: what is the correct answer here?
568  SD_DEBUG("SDEXT: access beyond the card size!" NL);
569  } else {
570  //fseek(sdf, _offset, SEEK_SET);
571  ret = lseek(sdfd, _offset, SEEK_SET);
572  if (ret != _offset) {
573  _read_b = 32; // address error, TODO: what is the correct answer here?
574  SD_DEBUG("SDEXT: seek error to %ld (got: %ld)" NL, _offset, ret);
575  } else {
576  _block_read();
577  if (cmd[0] == 18)
578  ans_callback = _block_read; // in case of CMD18, continue multiple sectors, register callback for that!
579  _read_b = 0; // R1
580  }
581  }
582  }
583  break;
584  case 24: // CMD24: write block
585  case 25: // CMD25: write multiple blocks
586  blocks = 0;
587  writing = -1; // signal writing (-2 for not-write mode), also the write position into the buffer
588  _read_b = 0; // R1 answer, OK
589  break;
590  default: // unimplemented command, heh!
591  SD_DEBUG("SDEXT: REGIO: unimplemented command %d = %02Xh" NL, cmd[0], cmd[0]);
592  _read_b = 4; // illegal command :-/
593  break;
594  }
595 }
596 
597 
598 
599 static void flash_erase ( int sector ) // erase sectors 0 or 1, or both if -1 is given!
600 {
601  if (sector < 1) {
602  memset(flash[0], 0xFF, 0xC000); // erase sector 0, it's only 48K accessible on SD/EP so it does not matter, real flash would be 64K here too
603  SD_DEBUG("SDEXT: FLASH: erasing sector 0!" NL);
604  WARNING_WINDOW("Erasing flash sector 0! You can safely ignore this warning.");
605  }
606  if (abs(sector) == 1) {
607  memset(flash[1], 0xFF, 0x10000); // erase sector 1
608  SD_DEBUG("SDEXT: FLASH: erasing sector 1!" NL);
609  WARNING_WINDOW("Erasing flash sector 1! You can safely ignore this warning.");
610  }
611 }
612 
613 
614 
615 static Uint8 flash_rd_bus_op ( int sector, Uint16 addr )
616 {
617  Uint8 byte;
618  if (flash_command == 0x90)
619  switch (addr & 0xFF) {
620  case 0x00:
621  byte = 1; // manufacturer ID
622  SD_DEBUG("SDEXT: FLASH: cmd 0x90 get manufacturer ID, result = %02Xh" NL, byte);
623  break;
624  case 0x02:
625  byte = 0x23; // device ID, top boot block
626  SD_DEBUG("SDEXT: FLASH: cmd 0x90 get device ID, result = %02Xh" NL, byte);
627  break;
628  case 0x04:
629  byte = 0; // sector protect status, etc?
630  SD_DEBUG("SDEXT: FLASH: cmd 0x90 get sector protect status, result = %02Xh" NL, byte);
631  break;
632  default:
633  byte = flash[sector][addr]; // not sure what to do in case of non-valid query "code"
634  SD_DEBUG("SDEXT: FLASH: cmd 0x90 unknown info requested (%d), accesssing flash content instead." NL, addr & 0xFF);
635  break;
636  }
637  else
638  byte = flash[sector][addr];
639  flash_command = 0;
640  flash_bus_cycle = 0;
641  return byte;
642 }
643 
644 
645 static int flash_warn_programming = 1;
646 static void flash_wr_bus_op ( int sector, Uint16 addr, Uint8 data )
647 {
648  int idaddr = addr & 0x3FFF;
649  if (flash_command == 0x90)
650  flash_bus_cycle = 0; // autoselect mode does not have wr cycles more (only rd)
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)
653  return; // write protection on flash, do not accept any write bus op
654  switch (flash_bus_cycle) {
655  case 0:
656  flash_command = 0; // invalidate command
657  if (data == 0xB0 || data == 0x30) {
658  //WARNING_WINDOW("SDEXT FLASH erase suspend/resume (cmd %02Xh) is not emulated yet :-(", data);
659  SD_DEBUG("SDEXT: FLASH: erase suspend/resume is not yet supported, ignoring ..." NL);
660  return; // well, erase suspend/resume is currently not supported :-(
661  }
662  if (data == 0xF0) {
663  SD_DEBUG("SDEXT: FLASH: reset command" NL);
664  return; // reset command
665  }
666  if (idaddr != 0xAAA || data != 0xAA) {
667  SD_DEBUG("SDEXT: FLASH: invalid command sequence at the beginning [bus_cycle=0]" NL);
668  return; // invalid cmd seq
669  }
670  flash_bus_cycle = 1;
671  return;
672  case 1:
673  if (idaddr != 0x555 || data != 0x55) { // invalid cmd seq
674  SD_DEBUG("SDEXT: FLASH: invalid command sequence [bus_cycle=1]" NL);
675  flash_bus_cycle = 0;
676  return;
677  }
678  flash_bus_cycle = 2;
679  return;
680  case 2:
681  if (idaddr != 0xAAA) {
682  SD_DEBUG("SDEXT: FLASH: invalid command sequence [bus_cycle=2]" NL);
683  flash_bus_cycle = 0; // invalid cmd seq
684  return;
685  }
686  if (data != 0x90 && data != 0x80 && data != 0xA0) {
687  SD_DEBUG("SDEXT: FLASH: unknown command [bus_cycle=2]" NL);
688  flash_bus_cycle = 0; // invalid cmd seq
689  return;
690  }
691  flash_command = data;
692  flash_bus_cycle = 3;
693  return;
694  case 3:
695  if (flash_command == 0xA0) { // program command!!!!
696  // flash programming allows only 1->0 on data bits, erase must be executed for 0->1
697  Uint8 oldbyte = flash[sector][addr];
698  Uint8 newbyte = oldbyte & data;
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;
704  }
705  flash_command = 0; // end of command
706  flash_bus_cycle = 0;
707  return;
708  }
709  // only flash command 0x80 can be left, 0x90 handled before "switch", 0xA0 just before ...
710  if (idaddr != 0xAAA || data != 0xAA) { // invalid cmd seq
711  SD_DEBUG("SDEXT: FLASH: invalid command sequence [bus_cycle=3]" NL);
712  flash_command = 0;
713  flash_bus_cycle = 0;
714  return;
715  }
716  flash_bus_cycle = 4;
717  return;
718  case 4: // only flash command 0x80 can get this far ...
719  if (idaddr != 0x555 || data != 0x55) { // invalid cmd seq
720  SD_DEBUG("SDEXT: FLASH: invalid command sequence [bus_cycle=4]" NL);
721  flash_command = 0;
722  flash_bus_cycle = 0;
723  return;
724  }
725  flash_bus_cycle = 5;
726  return;
727  case 5: // only flash command 0x80 can get this far ...
728  if (idaddr == 0xAAA && data == 0x10) { // CHIP ERASE!!!!
729  flash_erase(-1);
730  } else if (data == 0x30) {
731  flash_erase(sector);
732  }
733  flash_bus_cycle = 0; // end of erase command?
734  flash_command = 0;
735  return;
736  default:
737  FATAL("Invalid SDEXT FLASH bus cycle #%d on WR", flash_bus_cycle);
738  break;
739  }
740 }
741 
742 
743 
744 /* We expects all 4-7 seg reads/writes to be handled, as for re-flashing emu etc will need it!
745  Otherwise only segment 7 would be enough if flash is not emulated other than only "some kind of ROM". */
746 
747 Uint8 sdext_read_cart ( Uint16 addr )
748 {
749  SD_DEBUG("SDEXT: read cart @ %04X [CPU: seg=%02X, pc=%04X]" NL, addr, ports[0xB0 | (Z80_PC >> 14)], Z80_PC);
750  if (addr < 0xC000) {
751  Uint8 byte = flash_rd_bus_op(0, addr);
752  SD_DEBUG("SDEXT: reading base ROM, ROM offset = %04X, result = %02X" NL, addr, byte);
753  return byte;
754  }
755  if (addr < 0xE000) {
756  Uint8 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);
760  return byte;
761  }
762  if (addr < 0xFC00) {
763  addr -= 0xE000;
764  SD_DEBUG("SDEXT: reading RAM at offset %04X, result = %02X" NL, addr, sd_ram_ext[addr]);
765  return sd_ram_ext[addr];
766  }
767  if (is_hs_read) {
768  // in HS-read (high speed read) mode, all the 0x3C00-0x3FFF acts as data _read_ register (but not for _write_!!!)
769  // also, there is a fundamental difference compared to "normal" read: each reads triggers SPI shifting in HS mode, but not in regular mode, there only write does that!
770  Uint8 old = _read_b; // HS-read initiates an SPI shift, but the result (AFAIK) is the previous state, as shifting needs time!
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);
773  return old;
774  } else
775  switch (addr & 3) {
776  case 0:
777  // regular read (not HS) only gives the last shifted-in data, that's all!
778  SD_DEBUG("SDEXT: REGIO: R: DATA: SPI data register regular read %02X" NL, _read_b);
779  return _read_b;
780  case 1: // status reg: bit7=wp1, bit6=insert, bit5=changed (insert/changed=1: some of the cards not inserted or changed)
781  SD_DEBUG("SDEXT: REGIO: R: status" NL);
782  return status;
783  //return 0xFF - 32 + changed;
784  //return changed | 64;
785  case 2: // ROM pager [hmm not readble?!]
786  SD_DEBUG("SDEXT: REGIO: R: rom pager" NL);
787  return 0xFF;
788  return rom_page_ofs >> 8;
789  case 3: // HS read config is not readable?!]
790  SD_DEBUG("SDEXT: REGIO: R: HS config" NL);
791  return 0xFF;
792  return is_hs_read;
793  default:
794  FATAL("SDEXT: FATAL, unhandled (RD) case");
795  break;
796  }
797  FATAL("SDEXT: FATAL, control should not get here");
798  return 0; // make GCC happy :)
799 }
800 
801 
802 void sdext_write_cart ( Uint16 addr, Uint8 data )
803 {
804  SD_DEBUG("SDEXT: write cart @ %04X with %02X [CPU: seg=%02X, pc=%04X]" NL, addr, data, ports[0xB0 | (Z80_PC >> 14)], Z80_PC);
805  if (addr < 0xC000) { // segments 4-6, call flash WR emulation (sector 0, last 16K cannot be accessed by the EP ever!)
806  flash_wr_bus_op(0, addr, data);
807  return;
808  }
809  if (addr < 0xE000) { // pageable ROM (8K), call flash WR emulation with the right flash sector (1) and address offset in flash within the sector
810  flash_wr_bus_op(1, (addr & 0x1FFF) + rom_page_ofs, data);
811  return;
812  }
813  if (addr < 0xFC00) { // SDEXT's RAM (7K), writable
814  addr -= 0xE000;
815  SD_DEBUG("SDEXT: writing RAM at offset %04X" NL, addr);
816  sd_ram_ext[addr] = data;
817  return;
818  }
819  // rest 1K is the (memory mapped) I/O area
820  switch (addr & 3) {
821  case 0: // data register
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();
826  break;
827  case 1: // control register (bit7=CS0, bit6=CS1, bit5=clear change card signal
828  if (data & 32) // clear change signal
829  status &= 255 - 32;
830  cs0 = data & 128;
831  cs1 = data & 64;
832  SD_DEBUG("SDEXT: REGIO: W: control register to %02X CS0=%d CS1=%d" NL, data, cs0, cs1);
833  break;
834  case 2: // ROM pager register
835  rom_page_ofs = (data & 0xE0) << 8; // only high 3 bits count
836  SD_DEBUG("SDEXT: REGIO: W: paging ROM to %02X" NL, data);
837  break;
838  case 3: // HS (high speed) read mode to set: bit7=1
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");
842  break;
843  default:
844  FATAL("SDEXT: FATAL, unhandled (WR) case");
845  break;
846  }
847 }
848 
849 #endif
sdext.h
z80ex_w_states
void z80ex_w_states(unsigned w_states)
Definition: z80ex.c:307
emutools.h
xemu_open_file
int xemu_open_file(const char *filename, int mode, int *mode2, char *filepath_back)
Definition: emutools_files.c:469
WARNING_WINDOW
#define WARNING_WINDOW(...)
Definition: xep128.h:115
INFO_WINDOW
#define INFO_WINDOW(...)
Definition: xep128.h:114
addr
int addr
Definition: dma65.c:81
m65-memcontent-generator.data
data
Definition: m65-memcontent-generator.py:119
Uint32
uint32_t Uint32
Definition: fat32.c:49
Uint8
uint8_t Uint8
Definition: fat32.c:51
emutools_files.h
DEBUGPRINT
#define DEBUGPRINT(...)
Definition: emutools_basicdefs.h:171
ro
int ro
Definition: cpmfs.c:48
ERROR_WINDOW
#define ERROR_WINDOW(...)
Definition: xep128.h:116
cpu.h
NL
#define NL
Definition: fat32.c:37
compress_sd_image.r
def r
Definition: compress_sd_image.py:76
memory
Uint8 memory[0x100000]
Definition: commodore_65.c:43
PRINTF_LLD
#define PRINTF_LLD
Definition: emutools_basicdefs.h:145
XEMUEXIT
#define XEMUEXIT(n)
Definition: emutools_basicdefs.h:246
blocks
Uint32 blocks
Definition: fat32.c:73
size
int size
Definition: inject.c:37
Z80_PC
#define Z80_PC
Definition: z80ex.h:121
status
enum @26::@29 status
Uint16
uint16_t Uint16
Definition: fat32.c:50
ERRSTR
#define ERRSTR()
Definition: enterprise128.h:56
QUESTION_WINDOW
#define QUESTION_WINDOW(items, msg)
Definition: xep128.h:124
enterprise128.h
DEBUG
#define DEBUG(...)
Definition: emutools_basicdefs.h:167
FATAL
#define FATAL(...)
Definition: xep128.h:117
XEMU_OPEN_FILE_FIRST_MODE_USED
#define XEMU_OPEN_FILE_FIRST_MODE_USED
Definition: emutools_files.h:45
sdimg_path
char sdimg_path[PATH_MAX+1]
SDCARD_IMG_FN
#define SDCARD_IMG_FN
Definition: enterprise128.h:29