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