tc58128.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #include <assert.h>
  2. #include "hw.h"
  3. #include "sh.h"
  4. #include "sysemu.h"
  5. #define CE1 0x0100
  6. #define CE2 0x0200
  7. #define RE 0x0400
  8. #define WE 0x0800
  9. #define ALE 0x1000
  10. #define CLE 0x2000
  11. #define RDY1 0x4000
  12. #define RDY2 0x8000
  13. #define RDY(n) ((n) == 0 ? RDY1 : RDY2)
  14. typedef enum { WAIT, READ1, READ2, READ3 } state_t;
  15. typedef struct {
  16. uint8_t *flash_contents;
  17. state_t state;
  18. uint32_t address;
  19. uint8_t address_cycle;
  20. } tc58128_dev;
  21. static tc58128_dev tc58128_devs[2];
  22. #define FLASH_SIZE (16*1024*1024)
  23. static void init_dev(tc58128_dev * dev, const char *filename)
  24. {
  25. int ret, blocks;
  26. dev->state = WAIT;
  27. dev->flash_contents = qemu_mallocz(FLASH_SIZE);
  28. memset(dev->flash_contents, 0xff, FLASH_SIZE);
  29. if (!dev->flash_contents) {
  30. fprintf(stderr, "could not alloc memory for flash\n");
  31. exit(1);
  32. }
  33. if (filename) {
  34. /* Load flash image skipping the first block */
  35. ret = load_image(filename, dev->flash_contents + 528 * 32);
  36. if (ret < 0) {
  37. fprintf(stderr, "ret=%d\n", ret);
  38. fprintf(stderr, "qemu: could not load flash image %s\n",
  39. filename);
  40. exit(1);
  41. } else {
  42. /* Build first block with number of blocks */
  43. blocks = (ret + 528 * 32 - 1) / (528 * 32);
  44. dev->flash_contents[0] = blocks & 0xff;
  45. dev->flash_contents[1] = (blocks >> 8) & 0xff;
  46. dev->flash_contents[2] = (blocks >> 16) & 0xff;
  47. dev->flash_contents[3] = (blocks >> 24) & 0xff;
  48. fprintf(stderr, "loaded %d bytes for %s into flash\n", ret,
  49. filename);
  50. }
  51. }
  52. }
  53. static void handle_command(tc58128_dev * dev, uint8_t command)
  54. {
  55. switch (command) {
  56. case 0xff:
  57. fprintf(stderr, "reset flash device\n");
  58. dev->state = WAIT;
  59. break;
  60. case 0x00:
  61. fprintf(stderr, "read mode 1\n");
  62. dev->state = READ1;
  63. dev->address_cycle = 0;
  64. break;
  65. case 0x01:
  66. fprintf(stderr, "read mode 2\n");
  67. dev->state = READ2;
  68. dev->address_cycle = 0;
  69. break;
  70. case 0x50:
  71. fprintf(stderr, "read mode 3\n");
  72. dev->state = READ3;
  73. dev->address_cycle = 0;
  74. break;
  75. default:
  76. fprintf(stderr, "unknown flash command 0x%02x\n", command);
  77. assert(0);
  78. }
  79. }
  80. static void handle_address(tc58128_dev * dev, uint8_t data)
  81. {
  82. switch (dev->state) {
  83. case READ1:
  84. case READ2:
  85. case READ3:
  86. switch (dev->address_cycle) {
  87. case 0:
  88. dev->address = data;
  89. if (dev->state == READ2)
  90. dev->address |= 0x100;
  91. else if (dev->state == READ3)
  92. dev->address |= 0x200;
  93. break;
  94. case 1:
  95. dev->address += data * 528 * 0x100;
  96. break;
  97. case 2:
  98. dev->address += data * 528;
  99. fprintf(stderr, "address pointer in flash: 0x%08x\n",
  100. dev->address);
  101. break;
  102. default:
  103. /* Invalid data */
  104. assert(0);
  105. }
  106. dev->address_cycle++;
  107. break;
  108. default:
  109. assert(0);
  110. }
  111. }
  112. static uint8_t handle_read(tc58128_dev * dev)
  113. {
  114. #if 0
  115. if (dev->address % 0x100000 == 0)
  116. fprintf(stderr, "reading flash at address 0x%08x\n", dev->address);
  117. #endif
  118. return dev->flash_contents[dev->address++];
  119. }
  120. /* We never mark the device as busy, so interrupts cannot be triggered
  121. XXXXX */
  122. static int tc58128_cb(uint16_t porta, uint16_t portb,
  123. uint16_t * periph_pdtra, uint16_t * periph_portadir,
  124. uint16_t * periph_pdtrb, uint16_t * periph_portbdir)
  125. {
  126. int dev;
  127. if ((porta & CE1) == 0)
  128. dev = 0;
  129. else if ((porta & CE2) == 0)
  130. dev = 1;
  131. else
  132. return 0; /* No device selected */
  133. if ((porta & RE) && (porta & WE)) {
  134. /* Nothing to do, assert ready and return to input state */
  135. *periph_portadir &= 0xff00;
  136. *periph_portadir |= RDY(dev);
  137. *periph_pdtra |= RDY(dev);
  138. return 1;
  139. }
  140. if (porta & CLE) {
  141. /* Command */
  142. assert((porta & WE) == 0);
  143. handle_command(&tc58128_devs[dev], porta & 0x00ff);
  144. } else if (porta & ALE) {
  145. assert((porta & WE) == 0);
  146. handle_address(&tc58128_devs[dev], porta & 0x00ff);
  147. } else if ((porta & RE) == 0) {
  148. *periph_portadir |= 0x00ff;
  149. *periph_pdtra &= 0xff00;
  150. *periph_pdtra |= handle_read(&tc58128_devs[dev]);
  151. } else {
  152. assert(0);
  153. }
  154. return 1;
  155. }
  156. static sh7750_io_device tc58128 = {
  157. RE | WE, /* Port A triggers */
  158. 0, /* Port B triggers */
  159. tc58128_cb /* Callback */
  160. };
  161. int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2)
  162. {
  163. init_dev(&tc58128_devs[0], zone1);
  164. init_dev(&tc58128_devs[1], zone2);
  165. return sh7750_register_io_device(s, &tc58128);
  166. }