src/mess/machine/smartmed.c
| r6536 | r6537 | |
| 72 | 72 | int log2_pages_per_block; // log2 of number of pages per erase block (usually 4 or 5) |
| 73 | 73 | |
| 74 | 74 | UINT8 *data_ptr; // FEEPROM data area |
| 75 | UINT8 *data_uid_ptr; |
| 75 | 76 | |
| 76 | 77 | enum |
| 77 | 78 | { |
| r6536 | r6537 | |
| 80 | 81 | SM_M_PROGRAM, // program page data |
| 81 | 82 | SM_M_ERASE, // erase block data |
| 82 | 83 | SM_M_READSTATUS,// read status |
| 83 | | SM_M_READID // read ID |
| 84 | SM_M_READID, // read ID |
| 85 | SM_M_30 |
| 84 | 86 | } mode; // current operation mode |
| 85 | 87 | enum |
| 86 | 88 | { |
| r6536 | r6537 | |
| 97 | 99 | int accumulated_status; // accumulated status |
| 98 | 100 | |
| 99 | 101 | UINT8 *pagereg; // page register used by program command |
| 100 | | UINT8 id[2]; // chip ID |
| 102 | UINT8 id[3]; // chip ID |
| 101 | 103 | UINT8 mp_opcode; // multi-plane operation code |
| 104 | |
| 105 | int mode_3065; |
| 102 | 106 | }; |
| 103 | 107 | |
| 104 | 108 | |
| r6536 | r6537 | |
| 124 | 128 | sm->num_pages = 0; |
| 125 | 129 | sm->log2_pages_per_block = 0; |
| 126 | 130 | sm->data_ptr = NULL; |
| 131 | sm->data_uid_ptr = NULL; |
| 127 | 132 | sm->mode = SM_M_INIT; |
| 128 | 133 | sm->pointer_mode = SM_PM_A; |
| 129 | 134 | sm->page_addr = 0; |
| r6536 | r6537 | |
| 131 | 136 | sm->status = 0x40; |
| 132 | 137 | sm->accumulated_status = 0; |
| 133 | 138 | sm->pagereg = NULL; |
| 134 | | sm->id[0] = sm->id[1] = 0; |
| 139 | sm->id[0] = sm->id[1] = sm->id[2] = 0; |
| 135 | 140 | sm->mp_opcode = 0; |
| 141 | sm->mode_3065 = 0; |
| 136 | 142 | } |
| 137 | 143 | |
| 138 | 144 | /* |
| r6536 | r6537 | |
| 151 | 157 | return INIT_FAIL; |
| 152 | 158 | } |
| 153 | 159 | |
| 154 | | if (custom_header.version != 0) |
| 160 | if (custom_header.version > 1) |
| 155 | 161 | { |
| 156 | 162 | return INIT_FAIL; |
| 157 | 163 | } |
| r6536 | r6537 | |
| 161 | 167 | sm->num_pages = get_UINT32BE(custom_header.num_pages); |
| 162 | 168 | sm->log2_pages_per_block = get_UINT32BE(custom_header.log2_pages_per_block); |
| 163 | 169 | sm->data_ptr = auto_alloc_array(image->machine, UINT8, sm->page_total_size*sm->num_pages); |
| 170 | sm->data_uid_ptr = auto_alloc_array(image->machine, UINT8, 256 + 16); |
| 164 | 171 | sm->mode = SM_M_INIT; |
| 165 | 172 | sm->pointer_mode = SM_PM_A; |
| 166 | 173 | sm->page_addr = 0; |
| r6536 | r6537 | |
| 170 | 177 | sm->status |= 0x80; |
| 171 | 178 | sm->accumulated_status = 0; |
| 172 | 179 | sm->pagereg = auto_alloc_array(image->machine, UINT8, sm->page_total_size); |
| 173 | | sm->id[0] = sm->id[1] = 0; |
| 180 | sm->id[0] = sm->id[1] = sm->id[2] = 0; |
| 174 | 181 | |
| 175 | | image_fread(image, sm->id, 2); |
| 176 | | image_fread(image, &sm->mp_opcode, 1); |
| 182 | if (custom_header.version == 0) |
| 183 | { |
| 184 | image_fread(image, sm->id, 2); |
| 185 | image_fread(image, &sm->mp_opcode, 1); |
| 186 | } |
| 187 | else if (custom_header.version == 1) |
| 188 | { |
| 189 | image_fread(image, sm->id, 3); |
| 190 | image_fread(image, &sm->mp_opcode, 1); |
| 191 | image_fread(image, sm->data_uid_ptr, 256 + 16); |
| 192 | } |
| 177 | 193 | image_fread(image, sm->data_ptr, sm->page_total_size*sm->num_pages); |
| 178 | 194 | |
| 179 | 195 | return INIT_PASS; |
| r6536 | r6537 | |
| 191 | 207 | sm->num_pages = 0; |
| 192 | 208 | sm->log2_pages_per_block = 0; |
| 193 | 209 | sm->data_ptr = NULL; |
| 210 | sm->data_uid_ptr = NULL; |
| 194 | 211 | sm->mode = SM_M_INIT; |
| 195 | 212 | sm->pointer_mode = SM_PM_A; |
| 196 | 213 | sm->page_addr = 0; |
| r6536 | r6537 | |
| 198 | 215 | sm->status = 0x40; |
| 199 | 216 | sm->accumulated_status = 0; |
| 200 | 217 | sm->pagereg = auto_alloc_array(image->machine, UINT8, sm->page_total_size); |
| 201 | | sm->id[0] = sm->id[1] = 0; |
| 218 | sm->id[0] = sm->id[1] = sm->id[2] = 0; |
| 202 | 219 | sm->mp_opcode = 0; |
| 220 | sm->mode_3065 = 0; |
| 203 | 221 | |
| 204 | 222 | return; |
| 205 | 223 | } |
| r6536 | r6537 | |
| 233 | 251 | sm->pointer_mode = SM_PM_A; |
| 234 | 252 | sm->status = (sm->status & 0x80) | 0x40; |
| 235 | 253 | sm->accumulated_status = 0; |
| 254 | sm->mode_3065 = 0; |
| 236 | 255 | break; |
| 237 | 256 | case 0x00: |
| 238 | 257 | sm->mode = SM_M_READ; |
| r6536 | r6537 | |
| 317 | 336 | break;*/ |
| 318 | 337 | case 0x90: |
| 319 | 338 | sm->mode = SM_M_READID; |
| 339 | sm->addr_load_ptr = 0; |
| 320 | 340 | break; |
| 321 | 341 | /*case 0x91: |
| 322 | 342 | break;*/ |
| 343 | case 0x30: |
| 344 | sm->mode = SM_M_30; |
| 345 | break; |
| 346 | case 0x65: |
| 347 | if (sm->mode != SM_M_30) |
| 348 | { |
| 349 | logerror("smartmedia: unexpected address port write\n"); |
| 350 | sm->mode = SM_M_INIT; |
| 351 | } |
| 352 | else |
| 353 | { |
| 354 | sm->mode_3065 = 1; |
| 355 | } |
| 356 | break; |
| 323 | 357 | default: |
| 324 | 358 | logerror("smartmedia: unsupported command 0x%02x\n", data); |
| 325 | 359 | sm->mode = SM_M_INIT; |
| r6536 | r6537 | |
| 356 | 390 | sm->pointer_mode = SM_PM_A; |
| 357 | 391 | break; |
| 358 | 392 | case SM_PM_C: |
| 359 | | sm->byte_addr = (data & 0x0f) + sm->page_data_size; |
| 393 | if (!sm->mode_3065) |
| 394 | sm->byte_addr = (data & 0x0f) + sm->page_data_size; |
| 395 | else |
| 396 | sm->byte_addr = (data & 0x0f) + 256; |
| 360 | 397 | break; |
| 361 | 398 | } |
| 362 | 399 | } |
| r6536 | r6537 | |
| 371 | 408 | sm->addr_load_ptr++; |
| 372 | 409 | break; |
| 373 | 410 | case SM_M_READSTATUS: |
| 411 | case SM_M_30: |
| 374 | 412 | logerror("smartmedia: unexpected address port write\n"); |
| 375 | 413 | break; |
| 376 | 414 | case SM_M_READID: |
| r6536 | r6537 | |
| 395 | 433 | switch (sm->mode) |
| 396 | 434 | { |
| 397 | 435 | case SM_M_INIT: |
| 436 | case SM_M_30: |
| 398 | 437 | logerror("smartmedia: unexpected data port read\n"); |
| 399 | 438 | break; |
| 400 | 439 | case SM_M_READ: |
| 401 | | reply = sm->data_ptr[sm->page_addr*sm->page_total_size + sm->byte_addr]; |
| 440 | if (!sm->mode_3065) |
| 441 | reply = sm->data_ptr[sm->page_addr*sm->page_total_size + sm->byte_addr]; |
| 442 | else |
| 443 | reply = sm->data_uid_ptr[sm->page_addr*sm->page_total_size + sm->byte_addr]; |
| 402 | 444 | sm->byte_addr++; |
| 403 | 445 | if (sm->byte_addr == sm->page_total_size) |
| 404 | 446 | { |
| r6536 | r6537 | |
| 418 | 460 | reply = sm->status & 0xc1; |
| 419 | 461 | break; |
| 420 | 462 | case SM_M_READID: |
| 421 | | if (sm->byte_addr < 2) |
| 463 | if (sm->byte_addr < 3) |
| 422 | 464 | reply = sm->id[sm->byte_addr]; |
| 465 | sm->byte_addr++; |
| 423 | 466 | break; |
| 424 | 467 | } |
| 425 | 468 | |
| r6536 | r6537 | |
| 440 | 483 | { |
| 441 | 484 | case SM_M_INIT: |
| 442 | 485 | case SM_M_READ: |
| 486 | case SM_M_30: |
| 443 | 487 | logerror("smartmedia: unexpected data port write\n"); |
| 444 | 488 | break; |
| 445 | 489 | case SM_M_PROGRAM: |