fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 1495 lines 30 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/arch/macplus/sony.c * 7 * Created: 2007-11-15 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2007-2023 Hampa Hug <hampa@hampa.ch> * 9 *****************************************************************************/ 10 11/***************************************************************************** 12 * This program is free software. You can redistribute it and / or modify it * 13 * under the terms of the GNU General Public License version 2 as published * 14 * by the Free Software Foundation. * 15 * * 16 * This program is distributed in the hope that it will be useful, but * 17 * WITHOUT ANY WARRANTY, without even the implied warranty of * 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 19 * Public License for more details. * 20 *****************************************************************************/ 21 22 23#include "main.h" 24#include "sony.h" 25 26#include <string.h> 27 28#include <devices/memory.h> 29 30#include <drivers/block/block.h> 31#include <drivers/block/blkpsi.h> 32#include <drivers/psi/psi.h> 33 34#include <lib/log.h> 35 36 37#define MAC_HOOK_SONY 16 38#define MAC_HOOK_SONY_OPEN (MAC_HOOK_SONY + 0) 39#define MAC_HOOK_SONY_PRIME (MAC_HOOK_SONY + 1) 40#define MAC_HOOK_SONY_CTRL (MAC_HOOK_SONY + 2) 41#define MAC_HOOK_SONY_STATUS (MAC_HOOK_SONY + 3) 42#define MAC_HOOK_SONY_CLOSE (MAC_HOOK_SONY + 4) 43 44/* sony variable offsets */ 45#define SONY_TRACK 0 /* current track */ 46#define SONY_WPROT 2 /* FF = write protected, 00 = writeable */ 47#define SONY_DISKINPLACE 3 /* 0 = no disk, 1 = inserted, 2 = accessed */ 48#define SONY_INSTALLED 4 /* 0 = unknown, 1 = installed, ff = not installed */ 49#define SONY_SIDES 5 /* 0 single sided, ff double sided */ 50#define SONY_QLINK 6 51#define SONY_QTYPE 10 52#define SONY_QDRIVENO 12 53#define SONY_QREFNUM 14 /* driver reference number (0xfffb) */ 54#define SONY_QFSID 16 55#define SONY_TWOSIDEFMT 18 /* ff double-sided, 0 single-sided */ 56#define SONY_NEWIF 19 /* ff new 800K interface, 0 old 400K interface */ 57#define SONY_DRIVEERRS 20 /* drive soft errors */ 58 59/* parameter block offsets */ 60#define qLink 0 61#define qType 4 62#define ioTrap 6 63#define ioCmdAddr 8 64#define ioCompletion 12 65#define ioResult 16 66#define ioNamePtr 18 67#define ioVRefNum 22 68#define ioRefNum 24 69#define ioVersNum 26 70#define ioPermssn 27 71#define ioMisc 28 72#define ioBuffer 32 73#define ioReqCount 36 74#define ioActCount 40 75#define ioPosMode 44 76#define ioPosOffset 46 77#define csCode 26 78#define csParam 28 79 80/* device control entry offsets */ 81#define dCtlDriver 0 82#define dCtlFlags 4 83#define dCtlQHdr 6 84#define dCtlPosition 16 85#define dCtlStorage 20 86#define dCtlRefNum 24 87#define dCtlCurTicks 26 88 89/* positioning modes */ 90#define fsAtMark 0 91#define fsFromStart 1 92#define fsFromMark 3 93#define rdVerify 64 94 95/* trap word flags */ 96#define asyncTrpBit 0x0100 97#define noQueueBit 0x0200 98 99/* result codes */ 100#define noErr 0 101#define controlErr -17 102#define statusErr -18 103#define readErr -19 104#define writeErr -20 105#define abortErr -27 106#define wPrErr -44 107#define paramErr -50 108#define nsDrvErr -56 109#define noDriveErr -64 110#define offLineErr -65 111#define verErr -84 112 113 114void mac_sony_init (mac_sony_t *sony, int enable) 115{ 116 unsigned i; 117 118 sony->open = 0; 119 sony->patched = 0; 120 sony->enable = (enable != 0); 121 122 sony->mem = NULL; 123 sony->dsks = NULL; 124 125 sony->check_addr = 0; 126 sony->icon_addr[0] = 0; 127 sony->icon_addr[1] = 0; 128 129 sony->tag_buf = 0; 130 131 sony->format_hd_as_dd = 0; 132 sony->format_cnt = 0; 133 134 for (i = 0; i < SONY_DRIVES; i++) { 135 sony->delay_val[i] = 0; 136 sony->delay_cnt[i] = 0; 137 } 138} 139 140void mac_sony_free (mac_sony_t *sony) 141{ 142} 143 144void mac_sony_set_mem (mac_sony_t *sony, memory_t *mem) 145{ 146 sony->mem = mem; 147} 148 149void mac_sony_set_disks (mac_sony_t *sony, disks_t *dsks) 150{ 151 sony->dsks = dsks; 152} 153 154static 155unsigned long mac_sony_get_vars (mac_sony_t *sony, unsigned drive) 156{ 157 unsigned long ret; 158 159 ret = mem_get_uint32_be (sony->mem, 0x0134); 160 161 if ((drive >= 1) && (drive <= SONY_DRIVES)) { 162 ret += 8 + 66 * drive; 163 } 164 165 return (ret); 166} 167 168static 169unsigned long mac_sony_find_pcex (mac_sony_t *sony, unsigned long addr) 170{ 171 unsigned long cnt; 172 173 if (mem_get_uint32_be (sony->mem, addr) != 0x50434558) { 174 return (0); 175 } 176 177 cnt = mem_get_uint32_be (sony->mem, addr + 8); 178 179 if (cnt < 4) { 180 return (0); 181 } 182 183 sony->check_addr = addr + mem_get_uint32_be (sony->mem, addr + 16); 184 sony->icon_addr[0] = addr + mem_get_uint32_be (sony->mem, addr + 20); 185 sony->icon_addr[1] = addr + mem_get_uint32_be (sony->mem, addr + 24); 186 187 addr += mem_get_uint32_be (sony->mem, addr + 12); 188 189 return (addr); 190} 191 192static 193unsigned long mac_sony_find (mac_sony_t *sony, unsigned long addr, unsigned long size) 194{ 195 unsigned long sony_addr; 196 197 while (size > 0) { 198 addr += 1; 199 size -= 1; 200 201 if (mem_get_uint16_be (sony->mem, addr - 1) != 0x052e) { 202 continue; 203 } 204 205 if (mem_get_uint32_be (sony->mem, addr + 1) != 0x536f6e79) { 206 continue; 207 } 208 209 sony_addr = addr - 19; 210 211 if (mem_get_uint16_be (sony->mem, sony_addr) != 0x4f00) { 212 continue; 213 } 214 215 return (sony_addr); 216 } 217 218 return (0); 219} 220 221static 222void mac_sony_unpatch_rom (mac_sony_t *sony) 223{ 224 unsigned i, j; 225 unsigned sofs; 226 unsigned long sadr; 227 unsigned char *buf; 228 229 if (sony->patched == 0) { 230 return; 231 } 232 233 if ((sony->sony_addr == 0) || (sony->pcex_addr == 0)) { 234 return; 235 } 236 237 buf = sony->patch_buf; 238 239 for (i = 0; i < 5; i++) { 240 sofs = mem_get_uint16_be (sony->mem, sony->sony_addr + 8 + 2 * i); 241 sadr = sony->sony_addr + sofs; 242 243 for (j = 0; j < 6; j++) { 244 mem_set_uint8_rw (sony->mem, sadr + j, *(buf++)); 245 } 246 } 247 248 sony->patched = 0; 249} 250 251static 252void mac_sony_patch_rom (mac_sony_t *sony) 253{ 254 unsigned i, j; 255 unsigned sofs, dofs; 256 unsigned long sadr, dadr; 257 unsigned char *buf; 258 259 if ((sony->sony_addr == 0) || (sony->pcex_addr == 0)) { 260 return; 261 } 262 263 buf = sony->patch_buf; 264 265 for (i = 0; i < 5; i++) { 266 sofs = mem_get_uint16_be (sony->mem, sony->sony_addr + 8 + 2 * i); 267 sadr = sony->sony_addr + sofs; 268 269 dofs = mem_get_uint16_be (sony->mem, sony->pcex_addr + 8 + 2 * i); 270 dadr = sony->pcex_addr + dofs; 271 272 for (j = 0; j < 6; j++) { 273 *(buf++) = mem_get_uint8 (sony->mem, sadr + j); 274 } 275 276 mem_set_uint8_rw (sony->mem, sadr + 0, 0x4e); 277 mem_set_uint8_rw (sony->mem, sadr + 1, 0xf9); 278 mem_set_uint8_rw (sony->mem, sadr + 2, (dadr >> 24) & 0xff); 279 mem_set_uint8_rw (sony->mem, sadr + 3, (dadr >> 16) & 0xff); 280 mem_set_uint8_rw (sony->mem, sadr + 4, (dadr >> 8) & 0xff); 281 mem_set_uint8_rw (sony->mem, sadr + 5, dadr & 0xff); 282 283#ifdef DEBUG_SONY 284 mac_log_deb ("sony: patch %u: %06lx -> %06lx\n", i, sadr, dadr); 285#endif 286 } 287} 288 289void mac_sony_patch (mac_sony_t *sony) 290{ 291 if (sony->enable == 0) { 292 return; 293 } 294 295 if (sony->patched) { 296 return; 297 } 298 299 sony->patched = 1; 300 301 sony->pcex_addr = 0; 302 sony->sony_addr = 0; 303 304 sony->pcex_addr = mac_sony_find_pcex (sony, 0xf80000); 305 306 if (sony->pcex_addr == 0) { 307 pce_log_tag (MSG_ERR, "SONY:", "PCE ROM extension not found\n"); 308 return; 309 } 310 311 pce_log_tag (MSG_INF, "SONY:", "PCE ROM extension at 0x%06lx\n", sony->pcex_addr); 312 313 sony->sony_addr = mac_sony_find (sony, 0x400000, 1024UL * 1024UL); 314 315 if (sony->sony_addr == 0) { 316 pce_log_tag (MSG_ERR, "SONY:", "sony driver not found\n"); 317 return; 318 } 319 320 pce_log_tag (MSG_INF, "SONY:", "sony driver at 0x%06lx\n", sony->sony_addr); 321 322 mac_sony_patch_rom (sony); 323} 324 325void mac_sony_set_delay (mac_sony_t *sony, unsigned drive, unsigned delay) 326{ 327 if (drive < SONY_DRIVES) { 328 sony->delay_val[drive] = delay; 329 sony->delay_cnt[drive] = delay; 330 } 331} 332 333void mac_sony_insert (mac_sony_t *sony, unsigned drive) 334{ 335 unsigned long vars; 336 disk_t *dsk; 337 338 if (sony->open == 0) { 339 return; 340 } 341 342 if ((drive < 1) || (drive > SONY_DRIVES)) { 343 return; 344 } 345 346 dsk = dsks_get_disk (sony->dsks, drive); 347 348 if (dsk == NULL) { 349 return; 350 } 351 352 vars = mac_sony_get_vars (sony, drive); 353 354 if (mem_get_uint8 (sony->mem, vars + SONY_DISKINPLACE) == 0x00) { 355 pce_log_tag (MSG_INF, "SONY:", "insert drive %u\n", drive); 356 357 mem_set_uint8 (sony->mem, vars + SONY_DISKINPLACE, 0x01); 358 359 if (dsk_get_block_cnt (dsk) < 1600) { 360 mem_set_uint8 (sony->mem, vars + SONY_TWOSIDEFMT, 0x00); 361 mem_set_uint8 (sony->mem, vars + SONY_SIDES, 0x00); 362 mem_set_uint8 (sony->mem, vars + SONY_NEWIF, 0x00); 363 } 364 else { 365 mem_set_uint8 (sony->mem, vars + SONY_TWOSIDEFMT, 0xff); 366 mem_set_uint8 (sony->mem, vars + SONY_SIDES, 0xff); 367 mem_set_uint8 (sony->mem, vars + SONY_NEWIF, 0xff); 368 } 369 370 if (dsk_get_readonly (dsk)) { 371 mem_set_uint8 (sony->mem, vars + SONY_WPROT, 0xff); 372 } 373 else { 374 mem_set_uint8 (sony->mem, vars + SONY_WPROT, 0x00); 375 } 376 } 377} 378 379/* 380 * Check if disks need to be inserted. 381 */ 382int mac_sony_check (mac_sony_t *sony) 383{ 384 int check; 385 unsigned i; 386 unsigned long vars; 387 disk_t *dsk; 388 389 if (sony->open == 0) { 390 return (0); 391 } 392 393 check = 0; 394 395 for (i = 0; i < SONY_DRIVES; i++) { 396 if (sony->delay_cnt[i] > 0) { 397 sony->delay_cnt[i] -= 1; 398 399 if (sony->delay_cnt[i] == 0) { 400 mac_sony_insert (sony, i + 1); 401 } 402 } 403 404 dsk = dsks_get_disk (sony->dsks, i + 1); 405 406 if (dsk != NULL) { 407 vars = mac_sony_get_vars (sony, i + 1); 408 409 if (mem_get_uint8 (sony->mem, vars + SONY_DISKINPLACE) == 0x01) { 410 check = 1; 411 } 412 } 413 } 414 415 return (check); 416} 417 418 419static 420void mac_sony_open (mac_sony_t *sony) 421{ 422#ifdef DEBUG_SONY 423 mac_log_deb ("sony: open\n"); 424#endif 425 426 sony->open = 1; 427 428 if (mac_sony_check (sony)) { 429 sony->pc = sony->check_addr; 430 } 431} 432 433 434static 435unsigned long mac_sony_get_pblk (mac_sony_t *sony, unsigned ofs, unsigned size) 436{ 437 if (size == 1) { 438 return (mem_get_uint8 (sony->mem, sony->a0 + ofs)); 439 } 440 else if (size == 2) { 441 return (mem_get_uint16_be (sony->mem, sony->a0 + ofs)); 442 } 443 else if (size == 4) { 444 return (mem_get_uint32_be (sony->mem, sony->a0 + ofs)); 445 } 446 447 return (0); 448} 449 450static 451void mac_sony_set_pblk (mac_sony_t *sony, unsigned ofs, unsigned size, unsigned long val) 452{ 453 if (size == 1) { 454 mem_set_uint8 (sony->mem, sony->a0 + ofs, val); 455 } 456 else if (size == 2) { 457 mem_set_uint16_be (sony->mem, sony->a0 + ofs, val); 458 } 459 else if (size == 4) { 460 mem_set_uint32_be (sony->mem, sony->a0 + ofs, val); 461 } 462} 463 464static 465unsigned long mac_sony_get_dctl (mac_sony_t *sony, unsigned ofs, unsigned size) 466{ 467 if (size == 1) { 468 return (mem_get_uint8 (sony->mem, sony->a1 + ofs)); 469 } 470 else if (size == 2) { 471 return (mem_get_uint16_be (sony->mem, sony->a1 + ofs)); 472 } 473 else if (size == 4) { 474 return (mem_get_uint32_be (sony->mem, sony->a1 + ofs)); 475 } 476 477 return (0); 478} 479 480static 481void mac_sony_set_dctl (mac_sony_t *sony, unsigned ofs, unsigned size, unsigned long val) 482{ 483 if (size == 1) { 484 mem_set_uint8 (sony->mem, sony->a1 + ofs, val); 485 } 486 else if (size == 2) { 487 mem_set_uint16_be (sony->mem, sony->a1 + ofs, val); 488 } 489 else if (size == 4) { 490 mem_set_uint32_be (sony->mem, sony->a1 + ofs, val); 491 } 492} 493 494static 495void mac_sony_return (mac_sony_t *sony, unsigned res, int rts) 496{ 497 unsigned trap; 498 unsigned long val; 499 500 sony->d0 = (res & 0x8000) ? (0xffff0000 | res) : 0; 501 502 trap = mac_sony_get_pblk (sony, ioTrap, 2); 503 504 mac_sony_set_pblk (sony, ioResult, 2, res); 505 506 if ((rts == 0) && ((trap & noQueueBit) == 0)) { 507 val = mem_get_uint32_be (sony->mem, 0x0134); 508 val = mem_get_uint32_be (sony->mem, val); 509 510 sony->a1 = val; 511 sony->pc = mem_get_uint32_be (sony->mem, 0x08fc); 512 } 513} 514 515 516static 517unsigned long mac_sony_get_offset (mac_sony_t *sony) 518{ 519 unsigned posmode; 520 unsigned long ofs; 521 522 posmode = mac_sony_get_pblk (sony, ioPosMode, 2); 523 524 switch (posmode & 0x0f) { 525 case fsAtMark: 526 ofs = mac_sony_get_dctl (sony, dCtlPosition, 4); 527 break; 528 529 case fsFromStart: 530 ofs = mac_sony_get_pblk (sony, ioPosOffset, 4); 531 break; 532 533 case fsFromMark: 534 ofs = mac_sony_get_pblk (sony, ioPosOffset, 4); 535 ofs += mac_sony_get_dctl (sony, dCtlPosition, 4); 536 break; 537 538 default: 539 return (0); 540 } 541 542 return (ofs); 543} 544 545/* 546 * Get the disk type from a number of blocks 547 */ 548static 549unsigned mac_sony_get_disk_type (unsigned long blk) 550{ 551 if (blk < ((800 + 1440) / 2)) { 552 return (0); 553 } 554 else if (blk < ((1440 + 1600) / 2)) { 555 return (2); 556 } 557 else if (blk < ((1600 + 2880) / 2)) { 558 return (1); 559 } 560 else if (blk < (2 * 2880)) { 561 return (3); 562 } 563 564 return (255); 565} 566 567static 568int mac_sony_get_chs (unsigned long blk, unsigned long lba, unsigned *c, unsigned *h, unsigned *s) 569{ 570 unsigned type; 571 unsigned i, hn, sn; 572 573 type = mac_sony_get_disk_type (blk); 574 575 if ((type == 0) || (type == 1)) { 576 hn = (type == 0) ? 1 : 2; 577 sn = 12; 578 *c = 0; 579 580 for (i = 0; i < 5; i++) { 581 if (lba < (16 * hn * sn)) { 582 *s = (lba % sn); 583 *h = (lba / sn) % hn; 584 *c += lba / (sn * hn); 585 return (0); 586 } 587 588 lba -= 16 * hn * sn; 589 *c += 16; 590 sn -= 1; 591 } 592 593 return (1); 594 } 595 else if (type == 2) { 596 *s = (lba % 9) + 1; 597 *h = (lba / 9) % 2; 598 *c = lba / 18; 599 } 600 else if (type == 3) { 601 *s = (lba % 18) + 1; 602 *h = (lba / 18) % 2; 603 *c = lba / 36; 604 } 605 else { 606 mac_log_deb ("sony: chs error (blk=%lu, lba=%lu)\n", blk, lba); 607 return (1); 608 } 609 610 return (0); 611} 612 613static 614int mac_sony_read_block (disk_t *dsk, void *buf, void *tag, unsigned long idx) 615{ 616 unsigned c, h, s; 617 unsigned cnt; 618 619 if (dsk_get_type (dsk) != PCE_DISK_PSI) { 620 memset (tag, 0, 12); 621 622 if (dsk_read_lba (dsk, buf, idx, 1)) { 623 return (1); 624 } 625 626 return (0); 627 } 628 629 if (mac_sony_get_chs (dsk_get_block_cnt (dsk), idx, &c, &h, &s)) { 630 return (1); 631 } 632 633 dsk_psi_read_tags (dsk->ext, tag, 12, c, h, s, 0); 634 635 cnt = 512; 636 637 if (dsk_psi_read_chs (dsk->ext, buf, &cnt, c, h, s, 0) != PCE_BLK_PSI_OK) { 638 mac_log_deb ("sony: read error at %u/%u/%u\n", c, h, s); 639 return (1); 640 } 641 642 return (0); 643} 644 645static 646int mac_sony_write_block (disk_t *dsk, const void *buf, const void *tag, unsigned long idx) 647{ 648 unsigned c, h, s; 649 unsigned type; 650 unsigned cnt; 651 652 if (dsk_get_type (dsk) != PCE_DISK_PSI) { 653 if (dsk_write_lba (dsk, buf, idx, 1)) { 654 return (1); 655 } 656 657 return (0); 658 } 659 660 if (mac_sony_get_chs (dsk_get_block_cnt (dsk), idx, &c, &h, &s)) { 661 return (1); 662 } 663 664 type = mac_sony_get_disk_type (dsk_get_block_cnt (dsk)); 665 666 if ((type == 0) || (type == 1)) { 667 dsk_psi_write_tags (dsk->ext, tag, 12, c, h, s, 0); 668 } 669 670 cnt = 512; 671 672 if (dsk_psi_write_chs (dsk->ext, buf, &cnt, c, h, s, 0) != PCE_BLK_PSI_OK) { 673 mac_log_deb ("sony: write error at %u/%u/%u\n", c, h, s); 674 return (1); 675 } 676 677 return (0); 678} 679 680static 681void mac_sony_prime_read (mac_sony_t *sony, unsigned drive) 682{ 683 unsigned long addr, vars; 684 unsigned long ofs, cnt; 685 unsigned long i, n; 686 unsigned j; 687 disk_t *dsk; 688 unsigned char buf[512]; 689 unsigned char tag[12]; 690 unsigned posmode; 691 692 ofs = mac_sony_get_offset (sony); 693 cnt = mac_sony_get_pblk (sony, ioReqCount, 4); 694 addr = mac_sony_get_pblk (sony, ioBuffer, 4) & 0x00ffffff; 695 posmode = mac_sony_get_pblk (sony, ioPosMode, 2); 696 697#ifdef DEBUG_SONY 698 mac_log_deb ("sony: prime: read (drive=%u, ofs=0x%08lx, cnt=0x%04lx, addr=0x%08lx)\n", 699 drive, ofs, cnt, addr 700 ); 701#endif 702 703 dsk = dsks_get_disk (sony->dsks, drive); 704 705 if (dsk == NULL) { 706 mac_sony_return (sony, offLineErr, 0); 707 return; 708 } 709 710 if (posmode & 0x40) { 711 /* verify */ 712 mac_sony_return (sony, noErr, 0); 713 return; 714 } 715 716 if ((ofs & 511) || (cnt & 511)) { 717 mac_log_deb ("sony: non-aligned read\n"); 718 mac_sony_return (sony, paramErr, 0); 719 return; 720 } 721 722 n = cnt / 512; 723 724 for (i = 0; i < n; i++) { 725 if (mac_sony_read_block (dsk, buf, tag, (ofs / 512) + i)) { 726 mac_log_deb ("sony: read error at block %lu\n", 727 (ofs / 512) + i 728 ); 729 mac_sony_return (sony, 0xffff, 0); 730 return; 731 } 732 733 for (j = 0; j < 512; j++) { 734 mem_set_uint8 (sony->mem, addr + 512 * i + j, buf[j]); 735 } 736 737 for (j = 0; j < 12; j++) { 738 mem_set_uint8 (sony->mem, 0x2fc + j, tag[j]); 739 } 740 741 if (sony->tag_buf != 0) { 742 for (j = 0; j < 12; j++) { 743 mem_set_uint8 (sony->mem, sony->tag_buf + 12 * i + j, tag[j]); 744 } 745 } 746 } 747 748 vars = mac_sony_get_vars (sony, drive); 749 mem_set_uint8 (sony->mem, vars + SONY_DISKINPLACE, 0x02); 750 751 mac_sony_set_pblk (sony, ioActCount, 4, cnt); 752 753 ofs = mac_sony_get_dctl (sony, dCtlPosition, 4); 754 mac_sony_set_dctl (sony, dCtlPosition, 4, ofs + cnt); 755 756 mac_sony_return (sony, noErr, 0); 757} 758 759static 760void mac_sony_prime_write (mac_sony_t *sony, unsigned drive) 761{ 762 unsigned long addr; 763 unsigned long ofs, cnt; 764 unsigned relblk; 765 unsigned long i, n; 766 unsigned j; 767 disk_t *dsk; 768 unsigned char buf[512]; 769 unsigned char tag[12]; 770 771 ofs = mac_sony_get_offset (sony); 772 cnt = mac_sony_get_pblk (sony, ioReqCount, 4); 773 addr = mac_sony_get_pblk (sony, ioBuffer, 4) & 0x00ffffff; 774 775#ifdef DEBUG_SONY 776 mac_log_deb ("sony: prime: write (drive=%u, ofs=0x%08lx, cnt=0x%04lx, addr=0x%08lx)\n", 777 drive, ofs, cnt, addr 778 ); 779#endif 780 781 dsk = dsks_get_disk (sony->dsks, drive); 782 783 if (dsk == NULL) { 784 mac_sony_return (sony, offLineErr, 0); 785 return; 786 } 787 788 if (dsk_get_readonly (dsk)) { 789 mac_sony_return (sony, wPrErr, 0); 790 return; 791 } 792 793 if ((cnt & 511) || (ofs & 511)) { 794 mac_log_deb ("sony: non-aligned write\n"); 795 mac_sony_return (sony, paramErr, 0); 796 return; 797 } 798 799 memset (tag, 0, 12); 800 801 relblk = mem_get_uint16_be (sony->mem, 0x302); 802 803 n = cnt / 512; 804 805 for (i = 0; i < n; i++) { 806 for (j = 0; j < 512; j++) { 807 buf[j] = mem_get_uint8 (sony->mem, addr + 512 * i + j); 808 } 809 810 if (sony->tag_buf != 0) { 811 for (j = 0; j < 12; j++) { 812 tag[j] = mem_get_uint8 (sony->mem, sony->tag_buf + 12 * i + j); 813 mem_set_uint8 (sony->mem, 0x2fc + j, tag[j]); 814 } 815 } 816 else { 817 mem_set_uint16_be (sony->mem, 0x302, relblk + i); 818 819 for (j = 0; j < 12; j++) { 820 tag[j] = mem_get_uint8 (sony->mem, 0x2fc + j); 821 } 822 } 823 824 if (mac_sony_write_block (dsk, buf, tag, (ofs / 512) + i)) { 825 mac_log_deb ("sony: write error at block %lu\n", 826 (ofs / 512) + i 827 ); 828 mac_sony_return (sony, 0xffff, 0); 829 return; 830 } 831 } 832 833 mac_sony_set_pblk (sony, ioActCount, 4, cnt); 834 835 ofs = mac_sony_get_dctl (sony, dCtlPosition, 4); 836 mac_sony_set_dctl (sony, dCtlPosition, 4, ofs + cnt); 837 838 mac_sony_return (sony, noErr, 0); 839} 840 841static 842void mac_sony_prime (mac_sony_t *sony) 843{ 844 unsigned long vars; 845 unsigned trap, vref; 846 847 trap = mac_sony_get_pblk (sony, ioTrap, 2); 848 vref = mac_sony_get_pblk (sony, ioVRefNum, 2); 849 850 if ((vref < 1) || (vref > SONY_DRIVES)) { 851 mac_sony_return (sony, nsDrvErr, 0); 852 return; 853 } 854 855 vars = mac_sony_get_vars (sony, vref); 856 857 if (mem_get_uint8 (sony->mem, vars + SONY_DISKINPLACE) == 0) { 858 mac_sony_return (sony, offLineErr, 0); 859 return; 860 } 861 862 mem_set_uint8 (sony->mem, vars + SONY_DISKINPLACE, 0x02); 863 864 switch (trap & 0xff) { 865 case 2: /* read */ 866 mac_sony_prime_read (sony, vref); 867 break; 868 869 case 3: /* write */ 870 mac_sony_prime_write (sony, vref); 871 break; 872 873 default: 874 mac_log_deb ("sony: prime: unknown (trap=0x%04x)\n", trap); 875 mac_sony_return (sony, 0xffef, 0); 876 break; 877 } 878} 879 880 881static 882int mac_sony_format (disk_t *dsk, unsigned long blk) 883{ 884 unsigned long i, n; 885 unsigned c, h, s, hn, sn; 886 unsigned type; 887 unsigned char buf[512]; 888 psi_sct_t *sct; 889 disk_psi_t *psi; 890 891 if (dsk_get_type (dsk) != PCE_DISK_PSI) { 892 n = dsk_get_block_cnt (dsk); 893 894 if (n != blk) { 895 return (1); 896 } 897 898 memset (buf, 0x00, 512); 899 900 for (i = 0; i < n; i++) { 901 dsk_write_lba (dsk, buf, i, 1); 902 } 903 904 return (0); 905 } 906 907 psi = dsk->ext; 908 909 memset (buf, 0, 12); 910 911 type = mac_sony_get_disk_type (blk); 912 913 dsk_psi_erase_disk (psi); 914 915 if ((type == 0) || (type == 1)) { 916 dsk_psi_set_encoding (psi, PSI_ENC_GCR); 917 918 hn = (type == 0) ? 1 : 2; 919 sn = 13; 920 921 for (c = 0; c < 80; c++) { 922 if ((c & 15) == 0) { 923 sn -= 1; 924 } 925 926 for (h = 0; h < hn; h++) { 927 for (s = 0; s < sn; s++) { 928 dsk_psi_format_sector (psi, c, h, c, h, s, 512, 0); 929 930 sct = psi_img_get_sector (psi->img, c, h, s, 1); 931 932 if (sct != NULL) { 933 psi_sct_set_tags (sct, buf, 12); 934 } 935 } 936 } 937 } 938 } 939 else if ((type == 2) || (type == 3)) { 940 dsk_psi_set_encoding (psi, (type == 2) ? PSI_ENC_MFM_DD : PSI_ENC_MFM_HD); 941 942 sn = (type == 2) ? 9 : 18; 943 944 for (c = 0; c < 80; c++) { 945 for (h = 0; h < 2; h++) { 946 for (s = 0; s < sn; s++) { 947 dsk_psi_format_sector (psi, c, h, c, h, s + 1, 512, 0); 948 } 949 } 950 } 951 } 952 else { 953 return (1); 954 } 955 956 mac_log_deb ("sony: formatted disk (%lu blocks)\n", dsk_get_block_cnt (dsk)); 957 958 return (0); 959} 960 961static 962void mac_sony_ctl_verify (mac_sony_t *sony) 963{ 964 unsigned vref; 965 disk_t *dsk; 966 967 vref = mac_sony_get_pblk (sony, ioVRefNum, 2); 968 969#ifdef DEBUG_SONY 970 mac_log_deb ("sony: control: verify (drive=%u)\n", vref); 971#endif 972 973 if ((vref < 1) || (vref > SONY_DRIVES)) { 974 mac_sony_return (sony, nsDrvErr, 0); 975 return; 976 } 977 978 dsk = dsks_get_disk (sony->dsks, vref); 979 980 if (dsk == NULL) { 981 mac_sony_return (sony, noDriveErr, 0); 982 return; 983 } 984 985 mac_sony_return (sony, noErr, 0); 986} 987 988static 989void mac_sony_ctl_eject (mac_sony_t *sony) 990{ 991 unsigned vref; 992 unsigned long vars; 993 994 vref = mac_sony_get_pblk (sony, ioVRefNum, 2); 995 996#ifdef DEBUG_SONY 997 mac_log_deb ("sony: control eject (drive=%u)\n", vref); 998#endif 999 1000 if ((vref < 1) || (vref > SONY_DRIVES)) { 1001 mac_sony_return (sony, nsDrvErr, 0); 1002 return; 1003 } 1004 1005 vars = mac_sony_get_vars (sony, vref); 1006 1007 mem_set_uint8 (sony->mem, vars + SONY_DISKINPLACE, 0x00); 1008 mem_set_uint8 (sony->mem, vars + SONY_WPROT, 0x00); 1009 mem_set_uint8 (sony->mem, vars + SONY_TWOSIDEFMT, 0x00); 1010 1011 mac_sony_return (sony, noErr, 0); 1012} 1013 1014static 1015void mac_sony_ctl_set_tag_buf (mac_sony_t *sony) 1016{ 1017 unsigned long tagbuf; 1018 1019 tagbuf = mac_sony_get_pblk (sony, csParam, 4); 1020 1021#ifdef DEBUG_SONY 1022 mac_log_deb ("sony: control: set tag buffer (buf=0x%08lx)\n", tagbuf); 1023#endif 1024 1025 sony->tag_buf = tagbuf & 0x00ffffff; 1026 1027 mac_sony_return (sony, noErr, 0); 1028} 1029 1030static 1031void mac_sony_ctl_format (mac_sony_t *sony) 1032{ 1033 unsigned vref, format; 1034 unsigned long blk; 1035 unsigned long vars; 1036 disk_t *dsk; 1037 1038 vref = mac_sony_get_pblk (sony, ioVRefNum, 2); 1039 format = mac_sony_get_pblk (sony, csParam, 2); 1040 1041#ifdef DEBUG_SONY 1042 mac_log_deb ("sony: control format (drive=%u, format=%u)\n", vref, format); 1043#endif 1044 1045 if ((vref < 1) || (vref > SONY_DRIVES)) { 1046 mac_sony_return (sony, nsDrvErr, 0); 1047 return; 1048 } 1049 1050 dsk = dsks_get_disk (sony->dsks, vref); 1051 1052 if (dsk == NULL) { 1053 mac_sony_return (sony, noDriveErr, 0); 1054 return; 1055 } 1056 1057 if (dsk->readonly) { 1058 mac_sony_return (sony, wPrErr, 0); 1059 return; 1060 } 1061 1062 if ((format > 0) && (format <= sony->format_cnt)) { 1063 blk = sony->format_list[2 * (format - 1)]; 1064 } 1065 else { 1066 blk = dsk_get_block_cnt (dsk); 1067 1068 if (dsk_get_type (dsk) == PCE_DISK_PSI) { 1069 if (format == 1) { 1070 blk = 800; 1071 } 1072 else if (format == 2) { 1073 blk = 1600; 1074 } 1075 1076 if (blk == 0) { 1077 blk = 800; 1078 } 1079 } 1080 } 1081 1082 if (mac_sony_format (dsk, blk)) { 1083 mac_sony_return (sony, paramErr, 0); 1084 return; 1085 } 1086 1087 vars = mac_sony_get_vars (sony, vref); 1088 mem_set_uint16_be (sony->mem, vars + 18, blk); 1089 mem_set_uint16_be (sony->mem, vars + 20, blk >> 16); 1090 1091 mac_sony_return (sony, noErr, 0); 1092} 1093 1094static 1095void mac_sony_ctl_get_icon (mac_sony_t *sony, int which) 1096{ 1097 unsigned vref; 1098 unsigned long addr, addr1, addr2; 1099 disk_t *dsk; 1100 1101 vref = mac_sony_get_pblk (sony, ioVRefNum, 2); 1102 1103#ifdef DEBUG_SONY 1104 mac_log_deb ("sony: control: get %s icon (drive=%u)\n", 1105 which ? "media" : "drive", vref 1106 ); 1107#endif 1108 1109 if ((vref < 1) || (vref > SONY_DRIVES)) { 1110 mac_sony_return (sony, nsDrvErr, 0); 1111 return; 1112 } 1113 1114 addr1 = sony->icon_addr[0]; 1115 addr2 = sony->icon_addr[1]; 1116 1117 dsk = dsks_get_disk (sony->dsks, vref); 1118 1119 if (dsk == NULL) { 1120 addr = addr1; 1121 } 1122 else { 1123 switch (dsk_get_block_cnt (dsk)) { 1124 case 800: 1125 case 1600: 1126 case 1440: 1127 case 2880: 1128 addr = addr1; 1129 break; 1130 1131 default: 1132 addr = addr2; 1133 break; 1134 } 1135 } 1136 1137 mac_sony_set_pblk (sony, csParam, 4, addr); 1138 1139 mac_sony_return (sony, noErr, 0); 1140} 1141 1142static 1143void mac_sony_ctl_get_drive_info (mac_sony_t *sony) 1144{ 1145 unsigned vref, val; 1146 1147 vref = mac_sony_get_pblk (sony, ioVRefNum, 2); 1148 1149#ifdef DEBUG_SONY 1150 mac_log_deb ("sony: control: get drive info (drive=%u)\n", vref); 1151#endif 1152 1153 if ((vref < 1) || (vref > SONY_DRIVES)) { 1154 mac_sony_return (sony, nsDrvErr, 0); 1155 return; 1156 } 1157 1158 val = vref - 1; 1159 val = ((val << 3) & 8) | ((val >> 1) & 1); 1160 1161 mac_sony_set_pblk (sony, csParam, 4, (val << 8) | 0x04); 1162 1163 mac_sony_return (sony, noErr, 0); 1164} 1165 1166static 1167void mac_sony_ctl_format_copy (mac_sony_t *sony) 1168{ 1169 unsigned i; 1170 unsigned vref, format, type; 1171 unsigned long data, tags; 1172 unsigned long idx, blk; 1173 unsigned char buf[512]; 1174 unsigned char tag[12]; 1175 disk_t *dsk; 1176 1177 vref = mac_sony_get_pblk (sony, ioVRefNum, 2); 1178 1179 format = mac_sony_get_pblk (sony, csParam, 2); 1180 data = mac_sony_get_pblk (sony, csParam + 2, 4); 1181 tags = mac_sony_get_pblk (sony, csParam + 6, 4); 1182 1183#ifdef DEBUG_SONY 1184 mac_log_deb ("sony: control: format/copy (drive=%u, format=%u, data=0x%08lx, tags=0x%08lx)\n", 1185 vref, format, data, tags 1186 ); 1187#endif 1188 1189 if ((vref < 1) || (vref > SONY_DRIVES)) { 1190 mac_sony_return (sony, nsDrvErr, 0); 1191 return; 1192 } 1193 1194 dsk = dsks_get_disk (sony->dsks, vref); 1195 1196 if (dsk == NULL) { 1197 mac_sony_return (sony, noDriveErr, 0); 1198 return; 1199 } 1200 1201 if (dsk->readonly) { 1202 mac_sony_return (sony, wPrErr, 0); 1203 return; 1204 } 1205 1206 if ((format > 0) && (format <= sony->format_cnt)) { 1207 blk = sony->format_list[2 * (format - 1)]; 1208 } 1209 else { 1210 mac_sony_return (sony, paramErr, 0); 1211 return; 1212 } 1213 1214 type = mac_sony_get_disk_type (blk); 1215 1216 if (mac_sony_format (dsk, blk)) { 1217 mac_sony_return (sony, paramErr, 0); 1218 return; 1219 } 1220 1221 data &= 0x00ffffff; 1222 tags &= 0x00ffffff; 1223 1224 memset (tag, 0, 12); 1225 1226 for (idx = 0; idx < blk; idx++) { 1227 for (i = 0; i < 512; i++) { 1228 buf[i] = mem_get_uint8 (sony->mem, data + i); 1229 } 1230 1231 if ((type != 2) && (type != 3)) { 1232 for (i = 0; i < 12; i++) { 1233 tag[i] = mem_get_uint8 (sony->mem, tags + i); 1234 } 1235 } 1236 1237 if (mac_sony_write_block (dsk, buf, tag, idx)) { 1238 mac_sony_return (sony, 0xffff, 0); 1239 return; 1240 } 1241 1242 data += 512; 1243 tags += 12; 1244 } 1245 1246 mac_sony_return (sony, noErr, 0); 1247} 1248 1249static 1250void mac_sony_control (mac_sony_t *sony) 1251{ 1252 unsigned cscode; 1253 1254 cscode = mac_sony_get_pblk (sony, csCode, 2); 1255 1256 switch (cscode) { 1257 case 1: /* kill io */ 1258 mac_sony_return (sony, abortErr, 1); 1259 break; 1260 1261 case 5: /* verify disk */ 1262 mac_sony_ctl_verify (sony); 1263 break; 1264 1265 case 7: /* eject disk */ 1266 mac_sony_ctl_eject (sony); 1267 return; 1268 1269 case 8: /* set tag buffer */ 1270 mac_sony_ctl_set_tag_buf (sony); 1271 break; 1272 1273 case 9: /* track cache control */ 1274 mac_sony_return (sony, 0xffc8, 0); 1275 break; 1276 1277 case 6: /* format disk */ 1278 mac_sony_ctl_format (sony); 1279 return; 1280 1281 case 21: /* get drive icon */ 1282 mac_sony_ctl_get_icon (sony, 0); 1283 return; 1284 1285 case 22: /* get media icon */ 1286 mac_sony_ctl_get_icon (sony, 1); 1287 return; 1288 1289 case 23: /* get drive info */ 1290 mac_sony_ctl_get_drive_info (sony); 1291 return; 1292 1293 case 21315: /* FmtCopy */ 1294 mac_sony_ctl_format_copy (sony); 1295 return; 1296 1297 default: 1298 mac_log_deb ("sony: control: unknown (opcode=0x%04x)\n", cscode); 1299 mac_sony_return (sony, controlErr, 0); 1300 return; 1301 } 1302} 1303 1304 1305static 1306void mac_sony_status_format_list (mac_sony_t *sony) 1307{ 1308 unsigned i; 1309 unsigned long ptr; 1310 unsigned vref, cnt; 1311 unsigned long blk; 1312 unsigned long *list; 1313 disk_t *dsk; 1314 1315 vref = mac_sony_get_pblk (sony, ioVRefNum, 2); 1316 cnt = mac_sony_get_pblk (sony, csParam, 2); 1317 ptr = mac_sony_get_pblk (sony, csParam + 2, 4); 1318 1319#ifdef DEBUG_SONY 1320 mac_log_deb ("sony: status: get format list (drive=%u, maxfmt=%u)\n", 1321 vref, cnt 1322 ); 1323#endif 1324 1325 if ((vref < 1) || (vref > SONY_DRIVES)) { 1326 mac_sony_return (sony, nsDrvErr, 0); 1327 return; 1328 } 1329 1330 dsk = dsks_get_disk (sony->dsks, vref); 1331 1332 if (dsk == NULL) { 1333 mac_sony_return (sony, noDriveErr, 0); 1334 return; 1335 } 1336 1337 blk = dsk_get_block_cnt (dsk); 1338 1339 list = sony->format_list; 1340 1341 if (dsk_get_type (dsk) == PCE_DISK_PSI) { 1342 sony->format_cnt = 4; 1343 1344 list[0] = 800; 1345 list[1] = 0x810a0050; 1346 list[2] = 1600; 1347 list[3] = 0x820a0050; 1348 list[4] = 1440; 1349 list[5] = 0x82090050; 1350 list[6] = 2880; 1351 list[7] = 0x92120050; 1352 1353 switch (mac_sony_get_disk_type (blk)) { 1354 case 0: 1355 list[1] |= 0x40000000; 1356 break; 1357 1358 case 1: 1359 list[3] |= 0x40000000; 1360 break; 1361 1362 case 2: 1363 list[5] |= 0x40000000; 1364 break; 1365 1366 case 3: 1367 default: 1368 if (sony->format_hd_as_dd) { 1369 list[7] |= 0x40000000; 1370 } 1371 else { 1372 sony->format_cnt = 1; 1373 list[0] = 2880; 1374 list[1] = 0xd2120050; 1375 } 1376 break; 1377 } 1378 } 1379 else { 1380 sony->format_cnt = 1; 1381 list[0] = blk; 1382 list[1] = 0; 1383 } 1384 1385 if (cnt > sony->format_cnt) { 1386 cnt = sony->format_cnt; 1387 } 1388 1389 for (i = 0; i < cnt; i++) { 1390 mem_set_uint32_be (sony->mem, ptr + 8 * i + 0, list[2 * i + 0]); 1391 mem_set_uint32_be (sony->mem, ptr + 8 * i + 4, list[2 * i + 1]); 1392 } 1393 1394 mac_sony_set_pblk (sony, csParam, 2, cnt); 1395 1396 mac_sony_return (sony, noErr, 0); 1397} 1398 1399static 1400void mac_sony_status_drive_status (mac_sony_t *sony) 1401{ 1402 unsigned i; 1403 unsigned vref, val; 1404 unsigned long src; 1405 disk_t *dsk; 1406 1407 vref = mac_sony_get_pblk (sony, ioVRefNum, 2); 1408 1409#ifdef DEBUG_SONY 1410 mac_log_deb ("sony: status: get drive status (drive=%u)\n", vref); 1411#endif 1412 1413 if ((vref < 1) || (vref > SONY_DRIVES)) { 1414 mac_sony_return (sony, nsDrvErr, 0); 1415 return; 1416 } 1417 1418 dsk = dsks_get_disk (sony->dsks, vref); 1419 1420 if (dsk == NULL) { 1421 mac_sony_return (sony, noDriveErr, 0); 1422 return; 1423 } 1424 1425 src = mac_sony_get_vars (sony, vref); 1426 1427 for (i = 0; i < 11; i++) { 1428 val = mem_get_uint16_be (sony->mem, src + 2 * i); 1429 mac_sony_set_pblk (sony, csParam + 2 * i, 2, val); 1430 } 1431 1432 mac_sony_return (sony, noErr, 0); 1433} 1434 1435static 1436void mac_sony_status (mac_sony_t *sony) 1437{ 1438 unsigned cscode; 1439 1440 cscode = mac_sony_get_pblk (sony, csCode, 2); 1441 1442 switch (cscode) { 1443 case 6: /* return format list */ 1444 mac_sony_status_format_list (sony); 1445 break; 1446 1447 case 8: /* drive status */ 1448 mac_sony_status_drive_status (sony); 1449 break; 1450 1451 default: 1452 mac_sony_return (sony, statusErr, 0); 1453 mac_log_deb ("sony: status: unknown (cs=0x%04x)\n", cscode); 1454 break; 1455 } 1456} 1457 1458int mac_sony_hook (mac_sony_t *sony, unsigned val) 1459{ 1460 switch (val) { 1461 case MAC_HOOK_SONY_OPEN: 1462 mac_sony_open (sony); 1463 return (0); 1464 1465 case MAC_HOOK_SONY_PRIME: 1466 mac_sony_prime (sony); 1467 return (0); 1468 1469 case MAC_HOOK_SONY_CTRL: 1470 mac_sony_control (sony); 1471 return (0); 1472 1473 case MAC_HOOK_SONY_STATUS: 1474 mac_sony_status (sony); 1475 return (0); 1476 1477 case MAC_HOOK_SONY_CLOSE: 1478 return (0); 1479 } 1480 1481 return (1); 1482} 1483 1484void mac_sony_reset (mac_sony_t *sony) 1485{ 1486 unsigned i; 1487 1488 mac_sony_unpatch_rom (sony); 1489 1490 sony->open = 0; 1491 1492 for (i = 0; i < SONY_DRIVES; i++) { 1493 sony->delay_cnt[i] = sony->delay_val[i]; 1494 } 1495}