this repo has no description
at main 1766 lines 37 kB view raw
1/* 2 GLOBGLUE.c 3 4 Copyright (C) 2003 Bernd Schmidt, Philip Cummins, Paul C. Pratt 5 6 You can redistribute this file and/or modify it under the terms 7 of version 2 of the GNU General Public License as published by 8 the Free Software Foundation. You should have received a copy 9 of the license along with this file; see the file COPYING. 10 11 This file is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 license for more details. 15*/ 16 17/* 18 GLOBal GLUE (or GLOB of GLUE) 19 20 Holds the program together. 21 22 Some code here adapted from "custom.c" in vMac by Philip Cummins, 23 in turn descended from code in the Un*x Amiga Emulator by 24 Bernd Schmidt. 25*/ 26 27#include "PICOMMON.h" 28 29/* 30 ReportAbnormalID unused 0x111D - 0x11FF 31*/ 32 33/* 34 ReportAbnormalID ranges unused 0x12xx - 0xFFxx 35*/ 36 37IMPORTPROC m68k_reset(void); 38IMPORTPROC IWM_Reset(void); 39IMPORTPROC SCC_Reset(void); 40IMPORTPROC SCSI_Reset(void); 41#if EmVIA1 42IMPORTPROC VIA1_Reset(void); 43#endif 44#if EmVIA2 45IMPORTPROC VIA2_Reset(void); 46#endif 47IMPORTPROC Sony_Reset(void); 48 49IMPORTPROC ExtnDisk_Access(CPTR p); 50IMPORTPROC ExtnSony_Access(CPTR p); 51#if EmVidCard 52IMPORTPROC ExtnVideo_Access(CPTR p); 53#endif 54 55IMPORTPROC Sony_SetQuitOnEject(void); 56 57IMPORTPROC m68k_IPLchangeNtfy(void); 58IMPORTPROC MINEM68K_Init( 59 ui3b *fIPL); 60 61IMPORTFUNC ui5b GetCyclesRemaining(void); 62IMPORTPROC SetCyclesRemaining(ui5b n); 63 64IMPORTPROC SetHeadATTel(ATTep p); 65IMPORTFUNC ATTep FindATTel(CPTR addr); 66 67IMPORTFUNC ui5b SCSI_Access(ui5b Data, blnr WriteMem, CPTR addr); 68IMPORTFUNC ui5b SCC_Access(ui5b Data, blnr WriteMem, CPTR addr); 69IMPORTFUNC ui5b IWM_Access(ui5b Data, blnr WriteMem, CPTR addr); 70#if EmVIA1 71IMPORTFUNC ui5b VIA1_Access(ui5b Data, blnr WriteMem, CPTR addr); 72#endif 73#if EmVIA2 74IMPORTFUNC ui5b VIA2_Access(ui5b Data, blnr WriteMem, CPTR addr); 75#endif 76#if EmASC 77IMPORTFUNC ui5b ASC_Access(ui5b Data, blnr WriteMem, CPTR addr); 78#endif 79 80IMPORTFUNC ui3r get_vm_byte(CPTR addr); 81IMPORTFUNC ui4r get_vm_word(CPTR addr); 82IMPORTFUNC ui5r get_vm_long(CPTR addr); 83 84IMPORTPROC put_vm_byte(CPTR addr, ui3r b); 85IMPORTPROC put_vm_word(CPTR addr, ui4r w); 86IMPORTPROC put_vm_long(CPTR addr, ui5r l); 87 88GLOBALVAR ui5r my_disk_icon_addr; 89 90GLOBALPROC customreset(void) 91{ 92 IWM_Reset(); 93 SCC_Reset(); 94 SCSI_Reset(); 95#if EmVIA1 96 VIA1_Reset(); 97#endif 98#if EmVIA2 99 VIA2_Reset(); 100#endif 101 Sony_Reset(); 102 Extn_Reset(); 103#if CurEmMd <= kEmMd_Plus 104 WantMacReset = trueblnr; 105 /* 106 kludge, code in Finder appears 107 to do RESET and not expect 108 to come back. Maybe asserting 109 the RESET somehow causes 110 other hardware compenents to 111 later reset the 68000. 112 */ 113#endif 114} 115 116GLOBALVAR ui3p RAM = nullpr; 117 118#if EmVidCard 119GLOBALVAR ui3p VidROM = nullpr; 120#endif 121 122#if IncludeVidMem 123GLOBALVAR ui3p VidMem = nullpr; 124#endif 125 126GLOBALVAR ui3b Wires[kNumWires]; 127 128 129#if WantDisasm 130IMPORTPROC m68k_WantDisasmContext(void); 131#endif 132 133#if WantDisasm 134GLOBALPROC dbglog_StartLine(void) 135{ 136 m68k_WantDisasmContext(); 137 dbglog_writeCStr(" "); 138} 139#endif 140 141#if dbglog_HAVE 142GLOBALPROC dbglog_WriteMemArrow(blnr WriteMem) 143{ 144 if (WriteMem) { 145 dbglog_writeCStr(" <- "); 146 } else { 147 dbglog_writeCStr(" -> "); 148 } 149} 150#endif 151 152#if dbglog_HAVE 153GLOBALPROC dbglog_AddrAccess(char *s, ui5r Data, 154 blnr WriteMem, ui5r addr) 155{ 156 dbglog_StartLine(); 157 dbglog_writeCStr(s); 158 dbglog_writeCStr("["); 159 dbglog_writeHex(addr); 160 dbglog_writeCStr("]"); 161 dbglog_WriteMemArrow(WriteMem); 162 dbglog_writeHex(Data); 163 dbglog_writeReturn(); 164} 165#endif 166 167#if dbglog_HAVE 168GLOBALPROC dbglog_Access(char *s, ui5r Data, blnr WriteMem) 169{ 170 dbglog_StartLine(); 171 dbglog_writeCStr(s); 172 dbglog_WriteMemArrow(WriteMem); 173 dbglog_writeHex(Data); 174 dbglog_writeReturn(); 175} 176#endif 177 178#if dbglog_HAVE 179GLOBALPROC dbglog_WriteNote(char *s) 180{ 181 dbglog_StartLine(); 182 dbglog_writeCStr(s); 183 dbglog_writeReturn(); 184} 185#endif 186 187#if dbglog_HAVE 188GLOBALPROC dbglog_WriteSetBool(char *s, blnr v) 189{ 190 dbglog_StartLine(); 191 dbglog_writeCStr(s); 192 dbglog_writeCStr(" <- "); 193 if (v) { 194 dbglog_writeCStr("1"); 195 } else { 196 dbglog_writeCStr("0"); 197 } 198 dbglog_writeReturn(); 199} 200#endif 201 202#if WantAbnormalReports 203LOCALVAR blnr GotOneAbnormal = falseblnr; 204#endif 205 206#ifndef ReportAbnormalInterrupt 207#define ReportAbnormalInterrupt 0 208#endif 209 210#if WantAbnormalReports 211GLOBALPROC DoReportAbnormalID(ui4r id 212#if dbglog_HAVE 213 , char *s 214#endif 215 ) 216{ 217#if dbglog_HAVE 218 dbglog_StartLine(); 219 dbglog_writeCStr("*** abnormal : "); 220 dbglog_writeCStr(s); 221 dbglog_writeReturn(); 222#endif 223 224 if (! GotOneAbnormal) { 225 WarnMsgAbnormalID(id); 226#if ReportAbnormalInterrupt 227 SetInterruptButton(trueblnr); 228#endif 229 GotOneAbnormal = trueblnr; 230 } 231} 232#endif 233 234/* map of address space */ 235 236#define kRAM_Base 0x00000000 /* when overlay off */ 237#if (CurEmMd == kEmMd_PB100) 238#define kRAM_ln2Spc 23 239#elif (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx) 240#define kRAM_ln2Spc 23 241#else 242#define kRAM_ln2Spc 22 243#endif 244 245#if IncludeVidMem 246#if CurEmMd == kEmMd_PB100 247#define kVidMem_Base 0x00FA0000 248#define kVidMem_ln2Spc 16 249#else 250#define kVidMem_Base 0x00540000 251#define kVidMem_ln2Spc 18 252#endif 253#endif 254 255#if CurEmMd == kEmMd_PB100 256#define kSCSI_Block_Base 0x00F90000 257#define kSCSI_ln2Spc 16 258#else 259#define kSCSI_Block_Base 0x00580000 260#define kSCSI_ln2Spc 19 261#endif 262 263#define kRAM_Overlay_Base 0x00600000 /* when overlay on */ 264#define kRAM_Overlay_Top 0x00800000 265 266#if CurEmMd == kEmMd_PB100 267#define kSCCRd_Block_Base 0x00FD0000 268#define kSCC_ln2Spc 16 269#else 270#define kSCCRd_Block_Base 0x00800000 271#define kSCC_ln2Spc 22 272#endif 273 274#if CurEmMd != kEmMd_PB100 275#define kSCCWr_Block_Base 0x00A00000 276#define kSCCWr_Block_Top 0x00C00000 277#endif 278 279#if CurEmMd == kEmMd_PB100 280#define kIWM_Block_Base 0x00F60000 281#define kIWM_ln2Spc 16 282#else 283#define kIWM_Block_Base 0x00C00000 284#define kIWM_ln2Spc 21 285#endif 286 287#if CurEmMd == kEmMd_PB100 288#define kVIA1_Block_Base 0x00F70000 289#define kVIA1_ln2Spc 16 290#else 291#define kVIA1_Block_Base 0x00E80000 292#define kVIA1_ln2Spc 19 293#endif 294 295#if CurEmMd == kEmMd_PB100 296#define kASC_Block_Base 0x00FB0000 297#define kASC_ln2Spc 16 298#endif 299#define kASC_Mask 0x00000FFF 300 301 302#if IncludeExtnPbufs 303LOCALFUNC tMacErr PbufTransferVM(CPTR Buffera, 304 tPbuf i, ui5r offset, ui5r count, blnr IsWrite) 305{ 306 tMacErr result; 307 ui5b contig; 308 ui3p Buffer; 309 310label_1: 311 if (0 == count) { 312 result = mnvm_noErr; 313 } else { 314 Buffer = get_real_address0(count, ! IsWrite, Buffera, &contig); 315 if (0 == contig) { 316 result = mnvm_miscErr; 317 } else { 318 PbufTransfer(Buffer, i, offset, contig, IsWrite); 319 offset += contig; 320 Buffera += contig; 321 count -= contig; 322 goto label_1; 323 } 324 } 325 326 return result; 327} 328#endif 329 330/* extension mechanism */ 331 332#if IncludeExtnPbufs 333#define kCmndPbufFeatures 1 334#define kCmndPbufNew 2 335#define kCmndPbufDispose 3 336#define kCmndPbufGetSize 4 337#define kCmndPbufTransfer 5 338#endif 339 340#if IncludeExtnPbufs 341LOCALPROC ExtnParamBuffers_Access(CPTR p) 342{ 343 tMacErr result = mnvm_controlErr; 344 345 switch (get_vm_word(p + ExtnDat_commnd)) { 346 case kCmndVersion: 347 put_vm_word(p + ExtnDat_version, 1); 348 result = mnvm_noErr; 349 break; 350 case kCmndPbufFeatures: 351 put_vm_long(p + ExtnDat_params + 0, 0); 352 result = mnvm_noErr; 353 break; 354 case kCmndPbufNew: 355 { 356 tPbuf Pbuf_No; 357 ui5b count = get_vm_long(p + ExtnDat_params + 4); 358 /* reserved word at offset 2, should be zero */ 359 result = PbufNew(count, &Pbuf_No); 360 put_vm_word(p + ExtnDat_params + 0, Pbuf_No); 361 } 362 break; 363 case kCmndPbufDispose: 364 { 365 tPbuf Pbuf_No = get_vm_word(p + ExtnDat_params + 0); 366 /* reserved word at offset 2, should be zero */ 367 result = CheckPbuf(Pbuf_No); 368 if (mnvm_noErr == result) { 369 PbufDispose(Pbuf_No); 370 } 371 } 372 break; 373 case kCmndPbufGetSize: 374 { 375 ui5r Count; 376 tPbuf Pbuf_No = get_vm_word(p + ExtnDat_params + 0); 377 /* reserved word at offset 2, should be zero */ 378 379 result = PbufGetSize(Pbuf_No, &Count); 380 if (mnvm_noErr == result) { 381 put_vm_long(p + ExtnDat_params + 4, Count); 382 } 383 } 384 break; 385 case kCmndPbufTransfer: 386 { 387 ui5r PbufCount; 388 tPbuf Pbuf_No = get_vm_word(p + ExtnDat_params + 0); 389 /* reserved word at offset 2, should be zero */ 390 ui5r offset = get_vm_long(p + ExtnDat_params + 4); 391 ui5r count = get_vm_long(p + ExtnDat_params + 8); 392 CPTR Buffera = get_vm_long(p + ExtnDat_params + 12); 393 blnr IsWrite = 394 (get_vm_word(p + ExtnDat_params + 16) != 0); 395 result = PbufGetSize(Pbuf_No, &PbufCount); 396 if (mnvm_noErr == result) { 397 ui5r endoff = offset + count; 398 if ((endoff < offset) /* overflow */ 399 || (endoff > PbufCount)) 400 { 401 result = mnvm_eofErr; 402 } else { 403 result = PbufTransferVM(Buffera, 404 Pbuf_No, offset, count, IsWrite); 405 } 406 } 407 } 408 break; 409 } 410 411 put_vm_word(p + ExtnDat_result, result); 412} 413#endif 414 415#if IncludeExtnHostTextClipExchange 416#define kCmndHTCEFeatures 1 417#define kCmndHTCEExport 2 418#define kCmndHTCEImport 3 419#endif 420 421#if IncludeExtnHostTextClipExchange 422LOCALPROC ExtnHostTextClipExchange_Access(CPTR p) 423{ 424 tMacErr result = mnvm_controlErr; 425 426 switch (get_vm_word(p + ExtnDat_commnd)) { 427 case kCmndVersion: 428 put_vm_word(p + ExtnDat_version, 1); 429 result = mnvm_noErr; 430 break; 431 case kCmndHTCEFeatures: 432 put_vm_long(p + ExtnDat_params + 0, 0); 433 result = mnvm_noErr; 434 break; 435 case kCmndHTCEExport: 436 { 437 tPbuf Pbuf_No = get_vm_word(p + ExtnDat_params + 0); 438 439 result = CheckPbuf(Pbuf_No); 440 if (mnvm_noErr == result) { 441 result = HTCEexport(Pbuf_No); 442 } 443 } 444 break; 445 case kCmndHTCEImport: 446 { 447 tPbuf Pbuf_No; 448 result = HTCEimport(&Pbuf_No); 449 put_vm_word(p + ExtnDat_params + 0, Pbuf_No); 450 } 451 break; 452 } 453 454 put_vm_word(p + ExtnDat_result, result); 455} 456#endif 457 458#define kFindExtnExtension 0x64E1F58A 459#define kDiskDriverExtension 0x4C9219E6 460#if IncludeExtnPbufs 461#define kHostParamBuffersExtension 0x314C87BF 462#endif 463#if IncludeExtnHostTextClipExchange 464#define kHostClipExchangeExtension 0x27B130CA 465#endif 466 467#define kCmndFindExtnFind 1 468#define kCmndFindExtnId2Code 2 469#define kCmndFindExtnCount 3 470 471#define kParamFindExtnTheExtn 8 472#define kParamFindExtnTheId 12 473 474LOCALPROC ExtnFind_Access(CPTR p) 475{ 476 tMacErr result = mnvm_controlErr; 477 478 switch (get_vm_word(p + ExtnDat_commnd)) { 479 case kCmndVersion: 480 put_vm_word(p + ExtnDat_version, 1); 481 result = mnvm_noErr; 482 break; 483 case kCmndFindExtnFind: 484 { 485 ui5b extn = get_vm_long(p + kParamFindExtnTheExtn); 486 487 if (extn == kDiskDriverExtension) { 488 put_vm_word(p + kParamFindExtnTheId, kExtnDisk); 489 result = mnvm_noErr; 490 } else 491#if IncludeExtnPbufs 492 if (extn == kHostParamBuffersExtension) { 493 put_vm_word(p + kParamFindExtnTheId, 494 kExtnParamBuffers); 495 result = mnvm_noErr; 496 } else 497#endif 498#if IncludeExtnHostTextClipExchange 499 if (extn == kHostClipExchangeExtension) { 500 put_vm_word(p + kParamFindExtnTheId, 501 kExtnHostTextClipExchange); 502 result = mnvm_noErr; 503 } else 504#endif 505 if (extn == kFindExtnExtension) { 506 put_vm_word(p + kParamFindExtnTheId, 507 kExtnFindExtn); 508 result = mnvm_noErr; 509 } else 510 { 511 /* not found */ 512 } 513 } 514 break; 515 case kCmndFindExtnId2Code: 516 { 517 ui4r extn = get_vm_word(p + kParamFindExtnTheId); 518 519 if (extn == kExtnDisk) { 520 put_vm_long(p + kParamFindExtnTheExtn, 521 kDiskDriverExtension); 522 result = mnvm_noErr; 523 } else 524#if IncludeExtnPbufs 525 if (extn == kExtnParamBuffers) { 526 put_vm_long(p + kParamFindExtnTheExtn, 527 kHostParamBuffersExtension); 528 result = mnvm_noErr; 529 } else 530#endif 531#if IncludeExtnHostTextClipExchange 532 if (extn == kExtnHostTextClipExchange) { 533 put_vm_long(p + kParamFindExtnTheExtn, 534 kHostClipExchangeExtension); 535 result = mnvm_noErr; 536 } else 537#endif 538 if (extn == kExtnFindExtn) { 539 put_vm_long(p + kParamFindExtnTheExtn, 540 kFindExtnExtension); 541 result = mnvm_noErr; 542 } else 543 { 544 /* not found */ 545 } 546 } 547 break; 548 case kCmndFindExtnCount: 549 put_vm_word(p + kParamFindExtnTheId, kNumExtns); 550 result = mnvm_noErr; 551 break; 552 } 553 554 put_vm_word(p + ExtnDat_result, result); 555} 556 557#define kDSK_Params_Hi 0 558#define kDSK_Params_Lo 1 559#define kDSK_QuitOnEject 3 /* obsolete */ 560 561LOCALVAR ui4b ParamAddrHi; 562 563LOCALPROC Extn_Access(ui5b Data, CPTR addr) 564{ 565 switch (addr) { 566 case kDSK_Params_Hi: 567 ParamAddrHi = Data; 568 break; 569 case kDSK_Params_Lo: 570 { 571 CPTR p = ParamAddrHi << 16 | Data; 572 573 ParamAddrHi = (ui4b) - 1; 574 if (kcom_callcheck == get_vm_word(p + ExtnDat_checkval)) 575 { 576 put_vm_word(p + ExtnDat_checkval, 0); 577 578 switch (get_vm_word(p + ExtnDat_extension)) { 579 case kExtnFindExtn: 580 ExtnFind_Access(p); 581 break; 582#if EmVidCard 583 case kExtnVideo: 584 ExtnVideo_Access(p); 585 break; 586#endif 587#if IncludeExtnPbufs 588 case kExtnParamBuffers: 589 ExtnParamBuffers_Access(p); 590 break; 591#endif 592#if IncludeExtnHostTextClipExchange 593 case kExtnHostTextClipExchange: 594 ExtnHostTextClipExchange_Access(p); 595 break; 596#endif 597 case kExtnDisk: 598 ExtnDisk_Access(p); 599 break; 600 case kExtnSony: 601 ExtnSony_Access(p); 602 break; 603 default: 604 put_vm_word(p + ExtnDat_result, 605 mnvm_controlErr); 606 break; 607 } 608 } 609 } 610 break; 611 case kDSK_QuitOnEject: 612 /* obsolete, kept for compatibility */ 613 Sony_SetQuitOnEject(); 614 break; 615 } 616} 617 618GLOBALPROC Extn_Reset(void) 619{ 620 ParamAddrHi = (ui4b) - 1; 621} 622 623/* implementation of read/write for everything but RAM and ROM */ 624 625#define kSCC_Mask 0x03 626 627#if EmVIA1 628#define kVIA1_Mask 0x00000F 629#endif 630#if EmVIA2 631#define kVIA2_Mask 0x00000F 632#endif 633 634#define kIWM_Mask 0x00000F /* Allocated Memory Bandwidth for IWM */ 635 636#if CurEmMd <= kEmMd_512Ke 637#define ROM_CmpZeroMask 0 638#elif CurEmMd <= kEmMd_Plus 639#if kROM_Size > 0x00020000 640#define ROM_CmpZeroMask 0 /* For hacks like Mac ROM-inator */ 641#else 642#define ROM_CmpZeroMask 0x00020000 643#endif 644#elif CurEmMd <= kEmMd_PB100 645#define ROM_CmpZeroMask 0 646#elif CurEmMd <= kEmMd_IIx 647#define ROM_CmpZeroMask 0 648#else 649#error "ROM_CmpZeroMask not defined" 650#endif 651 652#define kROM_cmpmask (0x00F00000 | ROM_CmpZeroMask) 653 654#if CurEmMd <= kEmMd_512Ke 655#define Overlay_ROM_CmpZeroMask 0x00100000 656#elif CurEmMd <= kEmMd_Plus 657#define Overlay_ROM_CmpZeroMask 0x00020000 658#elif CurEmMd <= kEmMd_Classic 659#define Overlay_ROM_CmpZeroMask 0x00300000 660#elif CurEmMd <= kEmMd_PB100 661#define Overlay_ROM_CmpZeroMask 0 662#elif CurEmMd <= kEmMd_IIx 663#define Overlay_ROM_CmpZeroMask 0 664#else 665#error "Overlay_ROM_CmpZeroMask not defined" 666#endif 667 668enum { 669#if EmVIA1 670 kMMDV_VIA1, 671#endif 672#if EmVIA2 673 kMMDV_VIA2, 674#endif 675 kMMDV_SCC, 676 kMMDV_Extn, 677#if EmASC 678 kMMDV_ASC, 679#endif 680 kMMDV_SCSI, 681 kMMDV_IWM, 682 683 kNumMMDVs 684}; 685 686enum { 687#if CurEmMd >= kEmMd_SE 688 kMAN_OverlayOff, 689#endif 690 691 kNumMANs 692}; 693 694 695LOCALVAR ATTer ATTListA[MaxATTListN]; 696LOCALVAR ui4r LastATTel; 697 698 699LOCALPROC AddToATTList(ATTep p) 700{ 701 ui4r NewLast = LastATTel + 1; 702 if (NewLast >= MaxATTListN) { 703 ReportAbnormalID(0x1101, "MaxATTListN not big enough"); 704 } else { 705 ATTListA[LastATTel] = *p; 706 LastATTel = NewLast; 707 } 708} 709 710LOCALPROC InitATTList(void) 711{ 712 LastATTel = 0; 713} 714 715LOCALPROC FinishATTList(void) 716{ 717 { 718 /* add guard */ 719 ATTer r; 720 721 r.cmpmask = 0; 722 r.cmpvalu = 0; 723 r.usemask = 0; 724 r.usebase = nullpr; 725 r.Access = 0; 726 AddToATTList(&r); 727 } 728 729 { 730 ui4r i = LastATTel; 731 ATTep p = &ATTListA[LastATTel]; 732 ATTep h = nullpr; 733 734 while (0 != i) { 735 --i; 736 --p; 737 p->Next = h; 738 h = p; 739 } 740 741#if 0 /* verify list. not for final version */ 742 { 743 ATTep q1; 744 ATTep q2; 745 for (q1 = h; nullpr != q1->Next; q1 = q1->Next) { 746 if ((q1->cmpvalu & ~ q1->cmpmask) != 0) { 747 ReportAbnormalID(0x1102, "ATTListA bad entry"); 748 } 749 for (q2 = q1->Next; nullpr != q2->Next; q2 = q2->Next) { 750 ui5r common_mask = (q1->cmpmask) & (q2->cmpmask); 751 if ((q1->cmpvalu & common_mask) == 752 (q2->cmpvalu & common_mask)) 753 { 754 ReportAbnormalID(0x1103, "ATTListA Conflict"); 755 } 756 } 757 } 758 } 759#endif 760 761 SetHeadATTel(h); 762 } 763} 764 765#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx) 766LOCALPROC SetUp_RAM24(void) 767{ 768 ATTer r; 769 ui5r bankbit = 0x00100000 << (((VIA2_iA7 << 1) | VIA2_iA6) << 1); 770 771#if kRAMa_Size == kRAMb_Size 772 if (kRAMa_Size == bankbit) { 773 /* properly set up balanced RAM */ 774 r.cmpmask = 0x00FFFFFF & ~ ((1 << kRAM_ln2Spc) - 1); 775 r.cmpvalu = 0; 776 r.usemask = ((1 << kRAM_ln2Spc) - 1) & (kRAM_Size - 1); 777 r.usebase = RAM; 778 r.Access = kATTA_readwritereadymask; 779 AddToATTList(&r); 780 } else 781#endif 782 { 783 bankbit &= 0x00FFFFFF; /* if too large, always use RAMa */ 784 785 if (0 != bankbit) { 786#if kRAMb_Size != 0 787 r.cmpmask = bankbit 788 | (0x00FFFFFF & ~ ((1 << kRAM_ln2Spc) - 1)); 789 r.cmpvalu = bankbit; 790 r.usemask = ((1 << kRAM_ln2Spc) - 1) & (kRAMb_Size - 1); 791 r.usebase = kRAMa_Size + RAM; 792 r.Access = kATTA_readwritereadymask; 793 AddToATTList(&r); 794#endif 795 } 796 797 { 798 r.cmpmask = bankbit 799 | (0x00FFFFFF & ~ ((1 << kRAM_ln2Spc) - 1)); 800 r.cmpvalu = 0; 801 r.usemask = ((1 << kRAM_ln2Spc) - 1) & (kRAMa_Size - 1); 802 r.usebase = RAM; 803 r.Access = kATTA_readwritereadymask; 804 AddToATTList(&r); 805 } 806 } 807} 808#endif 809 810#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx) 811LOCALPROC SetUp_io(void) 812{ 813 ATTer r; 814 815 if (Addr32) { 816 r.cmpmask = 0xFF01E000; 817 r.cmpvalu = 0x50000000; 818 } else { 819 r.cmpmask = 0x00F1E000; 820 r.cmpvalu = 0x00F00000; 821 } 822 r.usebase = nullpr; 823 r.Access = kATTA_mmdvmask; 824 r.MMDV = kMMDV_VIA1; 825 AddToATTList(&r); 826 827 if (Addr32) { 828 r.cmpmask = 0xFF01E000; 829 r.cmpvalu = 0x50000000 | 0x2000; 830 } else { 831 r.cmpmask = 0x00F1E000; 832 r.cmpvalu = 0x00F00000 | 0x2000; 833 } 834 r.usebase = nullpr; 835 r.Access = kATTA_mmdvmask; 836 r.MMDV = kMMDV_VIA2; 837 AddToATTList(&r); 838 839 if (Addr32) { 840 r.cmpmask = 0xFF01E000; 841 r.cmpvalu = 0x50000000 | 0x4000; 842 } else { 843 r.cmpmask = 0x00F1E000; 844 r.cmpvalu = 0x00F00000 | 0x4000; 845 } 846 r.usebase = nullpr; 847 r.Access = kATTA_mmdvmask; 848 r.MMDV = kMMDV_SCC; 849 AddToATTList(&r); 850 851 if (Addr32) { 852 r.cmpmask = 0xFF01E000; 853 r.cmpvalu = 0x50000000 | 0x0C000; 854 } else { 855 r.cmpmask = 0x00F1E000; 856 r.cmpvalu = 0x00F00000 | 0x0C000; 857 } 858 r.usebase = nullpr; 859 r.Access = kATTA_mmdvmask; 860 r.MMDV = kMMDV_Extn; 861 AddToATTList(&r); 862 863 if (Addr32) { 864 r.cmpmask = 0xFF01E000; 865 r.cmpvalu = 0x50000000 | 0x10000; 866 } else { 867 r.cmpmask = 0x00F1E000; 868 r.cmpvalu = 0x00F00000 | 0x10000; 869 } 870 r.usebase = nullpr; 871 r.Access = kATTA_mmdvmask; 872 r.MMDV = kMMDV_SCSI; 873 AddToATTList(&r); 874 875 if (Addr32) { 876 r.cmpmask = 0xFF01E000; 877 r.cmpvalu = 0x50000000 | 0x14000; 878 } else { 879 r.cmpmask = 0x00F1E000; 880 r.cmpvalu = 0x00F00000 | 0x14000; 881 } 882 r.usebase = nullpr; 883 r.Access = kATTA_mmdvmask; 884 r.MMDV = kMMDV_ASC; 885 AddToATTList(&r); 886 887 if (Addr32) { 888 r.cmpmask = 0xFF01E000; 889 r.cmpvalu = 0x50000000 | 0x16000; 890 } else { 891 r.cmpmask = 0x00F1E000; 892 r.cmpvalu = 0x00F00000 | 0x16000; 893 } 894 r.usebase = nullpr; 895 r.Access = kATTA_mmdvmask; 896 r.MMDV = kMMDV_IWM; 897 AddToATTList(&r); 898 899#if 0 900 case 14: 901 /* 902 fail, nothing supposed to be here, 903 but rom accesses it anyway 904 */ 905 { 906 ui5r addr2 = addr & 0x1FFFF; 907 908 if ((addr2 != 0x1DA00) && (addr2 != 0x1DC00)) { 909 ReportAbnormalID(0x1104, "another unknown access"); 910 } 911 } 912 get_fail_realblock(p); 913 break; 914#endif 915} 916#endif 917 918#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx) 919LOCALPROC SetUp_address24(void) 920{ 921 ATTer r; 922 923#if 0 924 if (MemOverlay) { 925 ReportAbnormalID(0x1105, "Overlay with 24 bit addressing"); 926 } 927#endif 928 929 if (MemOverlay) { 930 r.cmpmask = Overlay_ROM_CmpZeroMask | 931 (0x00FFFFFF & ~ ((1 << kRAM_ln2Spc) - 1)); 932 r.cmpvalu = kRAM_Base; 933 r.usemask = kROM_Size - 1; 934 r.usebase = ROM; 935 r.Access = kATTA_readreadymask; 936 AddToATTList(&r); 937 } else { 938 SetUp_RAM24(); 939 } 940 941 r.cmpmask = kROM_cmpmask; 942 r.cmpvalu = kROM_Base; 943 r.usemask = kROM_Size - 1; 944 r.usebase = ROM; 945 r.Access = kATTA_readreadymask; 946 AddToATTList(&r); 947 948 r.cmpmask = 0x00FFFFFF & ~ (0x100000 - 1); 949 r.cmpvalu = 0x900000; 950 r.usemask = (kVidMemRAM_Size - 1) & (0x100000 - 1); 951 r.usebase = VidMem; 952 r.Access = kATTA_readwritereadymask; 953 AddToATTList(&r); 954#if kVidMemRAM_Size >= 0x00200000 955 r.cmpmask = 0x00FFFFFF & ~ (0x100000 - 1); 956 r.cmpvalu = 0xA00000; 957 r.usemask = (0x100000 - 1); 958 r.usebase = VidMem + (1 << 20); 959 r.Access = kATTA_readwritereadymask; 960 AddToATTList(&r); 961#endif 962#if kVidMemRAM_Size >= 0x00400000 963 r.cmpmask = 0x00FFFFFF & ~ (0x100000 - 1); 964 r.cmpvalu = 0xB00000; 965 r.usemask = (0x100000 - 1); 966 r.usebase = VidMem + (2 << 20); 967 r.Access = kATTA_readwritereadymask; 968 AddToATTList(&r); 969 r.cmpmask = 0x00FFFFFF & ~ (0x100000 - 1); 970 r.cmpvalu = 0xC00000; 971 r.usemask = (0x100000 - 1); 972 r.usebase = VidMem + (3 << 20); 973 r.Access = kATTA_readwritereadymask; 974 AddToATTList(&r); 975#endif 976 977 SetUp_io(); 978} 979#endif 980 981#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx) 982LOCALPROC SetUp_address32(void) 983{ 984 ATTer r; 985 986 if (MemOverlay) { 987 r.cmpmask = ~ ((1 << 30) - 1); 988 r.cmpvalu = 0; 989 r.usemask = kROM_Size - 1; 990 r.usebase = ROM; 991 r.Access = kATTA_readreadymask; 992 AddToATTList(&r); 993 } else { 994 ui5r bankbit = 995 0x00100000 << (((VIA2_iA7 << 1) | VIA2_iA6) << 1); 996#if kRAMa_Size == kRAMb_Size 997 if (kRAMa_Size == bankbit) { 998 /* properly set up balanced RAM */ 999 r.cmpmask = ~ ((1 << 30) - 1); 1000 r.cmpvalu = 0; 1001 r.usemask = kRAM_Size - 1; 1002 r.usebase = RAM; 1003 r.Access = kATTA_readwritereadymask; 1004 AddToATTList(&r); 1005 } else 1006#endif 1007 { 1008#if kRAMb_Size != 0 1009 r.cmpmask = bankbit | ~ ((1 << 30) - 1); 1010 r.cmpvalu = bankbit; 1011 r.usemask = kRAMb_Size - 1; 1012 r.usebase = kRAMa_Size + RAM; 1013 r.Access = kATTA_readwritereadymask; 1014 AddToATTList(&r); 1015#endif 1016 1017 r.cmpmask = bankbit | ~ ((1 << 30) - 1); 1018 r.cmpvalu = 0; 1019 r.usemask = kRAMa_Size - 1; 1020 r.usebase = RAM; 1021 r.Access = kATTA_readwritereadymask; 1022 AddToATTList(&r); 1023 } 1024 } 1025 1026 r.cmpmask = ~ ((1 << 28) - 1); 1027 r.cmpvalu = 0x40000000; 1028 r.usemask = kROM_Size - 1; 1029 r.usebase = ROM; 1030 r.Access = kATTA_readreadymask; 1031 AddToATTList(&r); 1032 1033#if 0 1034 /* haven't persuaded emulated computer to look here yet. */ 1035 /* NuBus super space */ 1036 r.cmpmask = ~ ((1 << 28) - 1); 1037 r.cmpvalu = 0x90000000; 1038 r.usemask = kVidMemRAM_Size - 1; 1039 r.usebase = VidMem; 1040 r.Access = kATTA_readwritereadymask; 1041 AddToATTList(&r); 1042#endif 1043 1044 /* Standard NuBus space */ 1045 r.cmpmask = ~ ((1 << 20) - 1); 1046 r.cmpvalu = 0xF9F00000; 1047 r.usemask = kVidROM_Size - 1; 1048 r.usebase = VidROM; 1049 r.Access = kATTA_readreadymask; 1050 AddToATTList(&r); 1051#if 0 1052 r.cmpmask = ~ 0x007FFFFF; 1053 r.cmpvalu = 0xF9000000; 1054 r.usemask = 0x007FFFFF & (kVidMemRAM_Size - 1); 1055 r.usebase = VidMem; 1056 r.Access = kATTA_readwritereadymask; 1057 AddToATTList(&r); 1058#endif 1059 1060 r.cmpmask = ~ 0x000FFFFF; 1061 r.cmpvalu = 0xF9900000; 1062 r.usemask = 0x000FFFFF & (kVidMemRAM_Size - 1); 1063 r.usebase = VidMem; 1064 r.Access = kATTA_readwritereadymask; 1065 AddToATTList(&r); 1066/* kludge to allow more than 1M of Video Memory */ 1067#if kVidMemRAM_Size >= 0x00200000 1068 r.cmpmask = ~ 0x000FFFFF; 1069 r.cmpvalu = 0xF9A00000; 1070 r.usemask = 0x000FFFFF & (kVidMemRAM_Size - 1); 1071 r.usebase = VidMem + (1 << 20); 1072 r.Access = kATTA_readwritereadymask; 1073 AddToATTList(&r); 1074#endif 1075#if kVidMemRAM_Size >= 0x00400000 1076 r.cmpmask = ~ 0x000FFFFF; 1077 r.cmpvalu = 0xF9B00000; 1078 r.usemask = 0x000FFFFF & (kVidMemRAM_Size - 1); 1079 r.usebase = VidMem + (2 << 20); 1080 r.Access = kATTA_readwritereadymask; 1081 AddToATTList(&r); 1082 r.cmpmask = ~ 0x000FFFFF; 1083 r.cmpvalu = 0xF9C00000; 1084 r.usemask = 0x000FFFFF & (kVidMemRAM_Size - 1); 1085 r.usebase = VidMem + (3 << 20); 1086 r.Access = kATTA_readwritereadymask; 1087 AddToATTList(&r); 1088#endif 1089 1090 SetUp_io(); 1091 1092#if 0 1093 if ((addr >= 0x58000000) && (addr < 0x58000004)) { 1094 /* test hardware. fail */ 1095 } 1096#endif 1097} 1098#endif 1099 1100#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx) 1101LOCALPROC SetUp_address(void) 1102{ 1103 if (Addr32) { 1104 SetUp_address32(); 1105 } else { 1106 SetUp_address24(); 1107 } 1108} 1109#endif 1110 1111/* 1112 unlike in the real Mac Plus, Mini vMac 1113 will allow misaligned memory access, 1114 since it is easier to allow it than 1115 it is to correctly simulate a bus error 1116 and back out of the current instruction. 1117*/ 1118 1119#ifndef ln2mtb 1120#define AddToATTListWithMTB AddToATTList 1121#else 1122LOCALPROC AddToATTListWithMTB(ATTep p) 1123{ 1124 /* 1125 Test of memory mapping system. 1126 */ 1127 ATTer r; 1128 1129 r.Access = p->Access; 1130 r.cmpmask = p->cmpmask | (1 << ln2mtb); 1131 r.usemask = p->usemask & ~ (1 << ln2mtb); 1132 1133 r.cmpvalu = p->cmpvalu + (1 << ln2mtb); 1134 r.usebase = p->usebase; 1135 AddToATTList(&r); 1136 1137 r.cmpvalu = p->cmpvalu; 1138 r.usebase = p->usebase + (1 << ln2mtb); 1139 AddToATTList(&r); 1140} 1141#endif 1142 1143#if (CurEmMd != kEmMd_II) && (CurEmMd != kEmMd_IIx) 1144LOCALPROC SetUp_RAM24(void) 1145{ 1146 ATTer r; 1147 1148#if (0 == kRAMb_Size) || (kRAMa_Size == kRAMb_Size) 1149 r.cmpmask = 0x00FFFFFF & ~ ((1 << kRAM_ln2Spc) - 1); 1150 r.cmpvalu = kRAM_Base; 1151 r.usemask = kRAM_Size - 1; 1152 r.usebase = RAM; 1153 r.Access = kATTA_readwritereadymask; 1154 AddToATTListWithMTB(&r); 1155#else 1156 /* unbalanced memory */ 1157 1158#if 0 != (0x00FFFFFF & kRAMa_Size) 1159 /* condition should always be true if configuration file right */ 1160 r.cmpmask = 0x00FFFFFF & (kRAMa_Size | ~ ((1 << kRAM_ln2Spc) - 1)); 1161 r.cmpvalu = kRAM_Base + kRAMa_Size; 1162 r.usemask = kRAMb_Size - 1; 1163 r.usebase = kRAMa_Size + RAM; 1164 r.Access = kATTA_readwritereadymask; 1165 AddToATTListWithMTB(&r); 1166#endif 1167 1168 r.cmpmask = 0x00FFFFFF & (kRAMa_Size | ~ ((1 << kRAM_ln2Spc) - 1)); 1169 r.cmpvalu = kRAM_Base; 1170 r.usemask = kRAMa_Size - 1; 1171 r.usebase = RAM; 1172 r.Access = kATTA_readwritereadymask; 1173 AddToATTListWithMTB(&r); 1174#endif 1175} 1176#endif 1177 1178#if (CurEmMd != kEmMd_II) && (CurEmMd != kEmMd_IIx) 1179LOCALPROC SetUp_address(void) 1180{ 1181 ATTer r; 1182 1183 if (MemOverlay) { 1184 r.cmpmask = Overlay_ROM_CmpZeroMask | 1185 (0x00FFFFFF & ~ ((1 << kRAM_ln2Spc) - 1)); 1186 r.cmpvalu = kRAM_Base; 1187 r.usemask = kROM_Size - 1; 1188 r.usebase = ROM; 1189 r.Access = kATTA_readreadymask; 1190 AddToATTListWithMTB(&r); 1191 } else { 1192 SetUp_RAM24(); 1193 } 1194 1195 r.cmpmask = kROM_cmpmask; 1196 r.cmpvalu = kROM_Base; 1197#if (CurEmMd >= kEmMd_SE) 1198 if (MemOverlay) { 1199 r.usebase = nullpr; 1200 r.Access = kATTA_ntfymask; 1201 r.Ntfy = kMAN_OverlayOff; 1202 AddToATTList(&r); 1203 } else 1204#endif 1205 { 1206 r.usemask = kROM_Size - 1; 1207 r.usebase = ROM; 1208 r.Access = kATTA_readreadymask; 1209 AddToATTListWithMTB(&r); 1210 } 1211 1212 if (MemOverlay) { 1213 r.cmpmask = 0x00E00000; 1214 r.cmpvalu = kRAM_Overlay_Base; 1215#if (0 == kRAMb_Size) || (kRAMa_Size == kRAMb_Size) 1216 r.usemask = kRAM_Size - 1; 1217 /* note that cmpmask and usemask overlap for 4M */ 1218 r.usebase = RAM; 1219 r.Access = kATTA_readwritereadymask; 1220#else 1221 /* unbalanced memory */ 1222 r.usemask = kRAMb_Size - 1; 1223 r.usebase = kRAMa_Size + RAM; 1224 r.Access = kATTA_readwritereadymask; 1225#endif 1226 AddToATTListWithMTB(&r); 1227 } 1228 1229#if IncludeVidMem 1230 r.cmpmask = 0x00FFFFFF & ~ ((1 << kVidMem_ln2Spc) - 1); 1231 r.cmpvalu = kVidMem_Base; 1232 r.usemask = kVidMemRAM_Size - 1; 1233 r.usebase = VidMem; 1234 r.Access = kATTA_readwritereadymask; 1235 AddToATTList(&r); 1236#endif 1237 1238 r.cmpmask = 0x00FFFFFF & ~ ((1 << kVIA1_ln2Spc) - 1); 1239 r.cmpvalu = kVIA1_Block_Base; 1240 r.usebase = nullpr; 1241 r.Access = kATTA_mmdvmask; 1242 r.MMDV = kMMDV_VIA1; 1243 AddToATTList(&r); 1244 1245 r.cmpmask = 0x00FFFFFF & ~ ((1 << kSCC_ln2Spc) - 1); 1246 r.cmpvalu = kSCCRd_Block_Base; 1247 r.usebase = nullpr; 1248 r.Access = kATTA_mmdvmask; 1249 r.MMDV = kMMDV_SCC; 1250 AddToATTList(&r); 1251 1252 r.cmpmask = 0x00FFFFFF & ~ ((1 << kExtn_ln2Spc) - 1); 1253 r.cmpvalu = kExtn_Block_Base; 1254 r.usebase = nullpr; 1255 r.Access = kATTA_mmdvmask; 1256 r.MMDV = kMMDV_Extn; 1257 AddToATTList(&r); 1258 1259#if CurEmMd == kEmMd_PB100 1260 r.cmpmask = 0x00FFFFFF & ~ ((1 << kASC_ln2Spc) - 1); 1261 r.cmpvalu = kASC_Block_Base; 1262 r.usebase = nullpr; 1263 r.Access = kATTA_mmdvmask; 1264 r.MMDV = kMMDV_ASC; 1265 AddToATTList(&r); 1266#endif 1267 1268 r.cmpmask = 0x00FFFFFF & ~ ((1 << kSCSI_ln2Spc) - 1); 1269 r.cmpvalu = kSCSI_Block_Base; 1270 r.usebase = nullpr; 1271 r.Access = kATTA_mmdvmask; 1272 r.MMDV = kMMDV_SCSI; 1273 AddToATTList(&r); 1274 1275 r.cmpmask = 0x00FFFFFF & ~ ((1 << kIWM_ln2Spc) - 1); 1276 r.cmpvalu = kIWM_Block_Base; 1277 r.usebase = nullpr; 1278 r.Access = kATTA_mmdvmask; 1279 r.MMDV = kMMDV_IWM; 1280 AddToATTList(&r); 1281} 1282#endif 1283 1284LOCALPROC SetUpMemBanks(void) 1285{ 1286 InitATTList(); 1287 1288 SetUp_address(); 1289 1290 FinishATTList(); 1291} 1292 1293#if 0 1294LOCALPROC get_fail_realblock(ATTep p) 1295{ 1296 p->cmpmask = 0; 1297 p->cmpvalu = 0xFFFFFFFF; 1298 p->usemask = 0; 1299 p->usebase = nullpr; 1300 p->Access = 0; 1301} 1302#endif 1303 1304GLOBALFUNC ui5b MMDV_Access(ATTep p, ui5b Data, 1305 blnr WriteMem, blnr ByteSize, CPTR addr) 1306{ 1307 switch (p->MMDV) { 1308#if EmVIA1 1309 case kMMDV_VIA1: 1310 if (! ByteSize) { 1311#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx) 1312 if (WriteMem && (addr == 0xF40006)) { 1313 /* for weirdness on shutdown in System 6 */ 1314#if 0 1315 VIA1_Access((Data >> 8) & 0x00FF, WriteMem, 1316 (addr >> 9) & kVIA1_Mask); 1317 VIA1_Access((Data) & 0x00FF, WriteMem, 1318 (addr >> 9) & kVIA1_Mask); 1319#endif 1320 } else 1321#endif 1322 { 1323 ReportAbnormalID(0x1106, "access VIA1 word"); 1324 } 1325 } else if ((addr & 1) != 0) { 1326 ReportAbnormalID(0x1107, "access VIA1 odd"); 1327 } else { 1328#if CurEmMd != kEmMd_PB100 1329#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx) 1330 if ((addr & 0x000001FE) != 0x00000000) 1331#else 1332 if ((addr & 0x000FE1FE) != 0x000FE1FE) 1333#endif 1334 { 1335 ReportAbnormalID(0x1108, 1336 "access VIA1 nonstandard address"); 1337 } 1338#endif 1339 Data = VIA1_Access(Data, WriteMem, 1340 (addr >> 9) & kVIA1_Mask); 1341 } 1342 1343 break; 1344#endif /* EmVIA1 */ 1345#if EmVIA2 1346 case kMMDV_VIA2: 1347 if (! ByteSize) { 1348 if ((! WriteMem) 1349 && ((0x3e00 == (addr & 0x1FFFF)) 1350 || (0x3e02 == (addr & 0x1FFFF)))) 1351 { 1352 /* for weirdness at offset 0x71E in ROM */ 1353 Data = 1354 (VIA2_Access(Data, WriteMem, 1355 (addr >> 9) & kVIA2_Mask) << 8) 1356 | VIA2_Access(Data, WriteMem, 1357 (addr >> 9) & kVIA2_Mask); 1358 1359 } else { 1360 ReportAbnormalID(0x1109, "access VIA2 word"); 1361 } 1362 } else if ((addr & 1) != 0) { 1363 if (0x3FFF == (addr & 0x1FFFF)) { 1364 /* 1365 for weirdness at offset 0x7C4 in ROM. 1366 looks like bug. 1367 */ 1368 Data = VIA2_Access(Data, WriteMem, 1369 (addr >> 9) & kVIA2_Mask); 1370 } else { 1371 ReportAbnormalID(0x110A, "access VIA2 odd"); 1372 } 1373 } else { 1374 if ((addr & 0x000001FE) != 0x00000000) { 1375 ReportAbnormalID(0x110B, 1376 "access VIA2 nonstandard address"); 1377 } 1378 Data = VIA2_Access(Data, WriteMem, 1379 (addr >> 9) & kVIA2_Mask); 1380 } 1381 break; 1382#endif /* EmVIA2 */ 1383 case kMMDV_SCC: 1384 1385#if (CurEmMd >= kEmMd_SE) \ 1386 && ! ((CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)) 1387 1388 if ((addr & 0x00100000) == 0) { 1389 ReportAbnormalID(0x110C, 1390 "access SCC unassigned address"); 1391 } else 1392#endif 1393 if (! ByteSize) { 1394 ReportAbnormalID(0x110D, "Attemped Phase Adjust"); 1395 } else 1396#if ! ((CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)) 1397 if (WriteMem != ((addr & 1) != 0)) { 1398 if (WriteMem) { 1399#if CurEmMd >= kEmMd_512Ke 1400#if CurEmMd != kEmMd_PB100 1401 ReportAbnormalID(0x110E, "access SCC even/odd"); 1402 /* 1403 This happens on boot with 64k ROM. 1404 */ 1405#endif 1406#endif 1407 } else { 1408 SCC_Reset(); 1409 } 1410 } else 1411#endif 1412#if (CurEmMd != kEmMd_PB100) \ 1413 && ! ((CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)) 1414 1415 if (WriteMem != (addr >= kSCCWr_Block_Base)) { 1416 ReportAbnormalID(0x110F, "access SCC wr/rd base wrong"); 1417 } else 1418#endif 1419 { 1420#if CurEmMd != kEmMd_PB100 1421#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx) 1422 if ((addr & 0x1FF9) != 0x00000000) 1423#else 1424 if ((addr & 0x001FFFF8) != 0x001FFFF8) 1425#endif 1426 { 1427 ReportAbnormalID(0x1110, 1428 "access SCC nonstandard address"); 1429 } 1430#endif 1431 Data = SCC_Access(Data, WriteMem, 1432 (addr >> 1) & kSCC_Mask); 1433 } 1434 break; 1435 case kMMDV_Extn: 1436 if (ByteSize) { 1437 ReportAbnormalID(0x1111, "access Sony byte"); 1438 } else if ((addr & 1) != 0) { 1439 ReportAbnormalID(0x1112, "access Sony odd"); 1440 } else if (! WriteMem) { 1441 ReportAbnormalID(0x1113, "access Sony read"); 1442 } else { 1443 Extn_Access(Data, (addr >> 1) & 0x0F); 1444 } 1445 break; 1446#if EmASC 1447 case kMMDV_ASC: 1448 if (! ByteSize) { 1449#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx) 1450 if (WriteMem) { 1451 (void) ASC_Access((Data >> 8) & 0x00FF, 1452 WriteMem, addr & kASC_Mask); 1453 Data = ASC_Access((Data) & 0x00FF, 1454 WriteMem, (addr + 1) & kASC_Mask); 1455 } else { 1456 Data = 1457 (ASC_Access((Data >> 8) & 0x00FF, 1458 WriteMem, addr & kASC_Mask) << 8) 1459 | ASC_Access((Data) & 0x00FF, 1460 WriteMem, (addr + 1) & kASC_Mask); 1461 } 1462#else 1463 ReportAbnormalID(0x1114, "access ASC word"); 1464#endif 1465 } else { 1466 Data = ASC_Access(Data, WriteMem, addr & kASC_Mask); 1467 } 1468 break; 1469#endif 1470 case kMMDV_SCSI: 1471 if (! ByteSize) { 1472 ReportAbnormalID(0x1115, "access SCSI word"); 1473 } else 1474#if ! ((CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)) 1475 if (WriteMem != ((addr & 1) != 0)) { 1476 ReportAbnormalID(0x1116, "access SCSI even/odd"); 1477 } else 1478#endif 1479 { 1480#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx) 1481 if ((addr & 0x1F8F) != 0x00000000) { 1482 ReportAbnormalID(0x1117, 1483 "access SCSI nonstandard address"); 1484 } 1485#endif 1486 Data = SCSI_Access(Data, WriteMem, (addr >> 4) & 0x07); 1487 } 1488 1489 break; 1490 case kMMDV_IWM: 1491#if (CurEmMd >= kEmMd_SE) \ 1492 && ! ((CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)) 1493 1494 if ((addr & 0x00100000) == 0) { 1495 ReportAbnormalID(0x1118, 1496 "access IWM unassigned address"); 1497 } else 1498#endif 1499 if (! ByteSize) { 1500#if ExtraAbnormalReports 1501 ReportAbnormalID(0x1119, "access IWM word"); 1502 /* 1503 This happens when quitting 'Glider 3.1.2'. 1504 perhaps a bad handle is being disposed of. 1505 */ 1506#endif 1507 } else 1508#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx) 1509 if ((addr & 1) != 0) { 1510 ReportAbnormalID(0x111A, "access IWM odd"); 1511 } else 1512#else 1513 if ((addr & 1) == 0) { 1514 ReportAbnormalID(0x111B, "access IWM even"); 1515 } else 1516#endif 1517 { 1518#if (CurEmMd != kEmMd_PB100) \ 1519 && ! ((CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)) 1520 1521 if ((addr & 0x001FE1FF) != 0x001FE1FF) { 1522 ReportAbnormalID(0x111C, 1523 "access IWM nonstandard address"); 1524 } 1525#endif 1526 Data = IWM_Access(Data, WriteMem, 1527 (addr >> 9) & kIWM_Mask); 1528 } 1529 1530 break; 1531 } 1532 1533 return Data; 1534} 1535 1536GLOBALFUNC blnr MemAccessNtfy(ATTep pT) 1537{ 1538 blnr v = falseblnr; 1539 1540 switch (pT->Ntfy) { 1541#if CurEmMd >= kEmMd_SE 1542 case kMAN_OverlayOff: 1543 pT->Access = kATTA_readreadymask; 1544 1545 MemOverlay = 0; 1546 SetUpMemBanks(); 1547 1548 v = trueblnr; 1549 1550 break; 1551#endif 1552 } 1553 1554 return v; 1555} 1556 1557GLOBALPROC MemOverlay_ChangeNtfy(void) 1558{ 1559#if CurEmMd <= kEmMd_Plus 1560 SetUpMemBanks(); 1561#elif (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx) 1562 SetUpMemBanks(); 1563#endif 1564} 1565 1566#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx) 1567GLOBALPROC Addr32_ChangeNtfy(void) 1568{ 1569 SetUpMemBanks(); 1570} 1571#endif 1572 1573LOCALFUNC ATTep get_address_realblock1(blnr WriteMem, CPTR addr) 1574{ 1575 ATTep p; 1576 1577Label_Retry: 1578 p = FindATTel(addr); 1579 if (0 != (p->Access & 1580 (WriteMem ? kATTA_writereadymask : kATTA_readreadymask))) 1581 { 1582 /* ok */ 1583 } else { 1584 if (0 != (p->Access & kATTA_ntfymask)) { 1585 if (MemAccessNtfy(p)) { 1586 goto Label_Retry; 1587 } 1588 } 1589 p = nullpr; /* fail */ 1590 } 1591 1592 return p; 1593} 1594 1595GLOBALFUNC ui3p get_real_address0(ui5b L, blnr WritableMem, CPTR addr, 1596 ui5b *actL) 1597{ 1598 ui5b bankleft; 1599 ui3p p; 1600 ATTep q; 1601 1602 q = get_address_realblock1(WritableMem, addr); 1603 if (nullpr == q) { 1604 *actL = 0; 1605 p = nullpr; 1606 } else { 1607 ui5r m2 = q->usemask & ~ q->cmpmask; 1608 ui5r m3 = m2 & ~ (m2 + 1); 1609 p = q->usebase + (addr & q->usemask); 1610 bankleft = (m3 + 1) - (addr & m3); 1611 if (bankleft >= L) { 1612 /* this block is big enough (by far the most common case) */ 1613 *actL = L; 1614 } else { 1615 *actL = bankleft; 1616 } 1617 } 1618 1619 return p; 1620} 1621 1622GLOBALVAR blnr InterruptButton = falseblnr; 1623 1624GLOBALPROC SetInterruptButton(blnr v) 1625{ 1626 if (InterruptButton != v) { 1627 InterruptButton = v; 1628 VIAorSCCinterruptChngNtfy(); 1629 } 1630} 1631 1632LOCALVAR ui3b CurIPL = 0; 1633 1634GLOBALPROC VIAorSCCinterruptChngNtfy(void) 1635{ 1636#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx) 1637 ui3b NewIPL; 1638 1639 if (InterruptButton) { 1640 NewIPL = 7; 1641 } else if (SCCInterruptRequest) { 1642 NewIPL = 4; 1643 } else if (VIA2_InterruptRequest) { 1644 NewIPL = 2; 1645 } else if (VIA1_InterruptRequest) { 1646 NewIPL = 1; 1647 } else { 1648 NewIPL = 0; 1649 } 1650#else 1651 ui3b VIAandNotSCC = VIA1_InterruptRequest 1652 & ~ SCCInterruptRequest; 1653 ui3b NewIPL = VIAandNotSCC 1654 | (SCCInterruptRequest << 1) 1655 | (InterruptButton << 2); 1656#endif 1657 if (NewIPL != CurIPL) { 1658 CurIPL = NewIPL; 1659 m68k_IPLchangeNtfy(); 1660 } 1661} 1662 1663GLOBALFUNC blnr AddrSpac_Init(void) 1664{ 1665 int i; 1666 1667 for (i = 0; i < kNumWires; i++) { 1668 Wires[i] = 1; 1669 } 1670 1671 MINEM68K_Init( 1672 &CurIPL); 1673 return trueblnr; 1674} 1675 1676GLOBALPROC Memory_Reset(void) 1677{ 1678 MemOverlay = 1; 1679 SetUpMemBanks(); 1680} 1681 1682#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx) 1683EXPORTPROC PowerOff_ChangeNtfy(void); 1684GLOBALPROC PowerOff_ChangeNtfy(void) 1685{ 1686 if (! VIA2_iB2) { 1687 ForceMacOff = trueblnr; 1688 } 1689} 1690#endif 1691 1692/* user event queue utilities */ 1693 1694#if HaveMasterMyEvtQLock 1695GLOBALVAR ui4r MasterMyEvtQLock = 0; 1696 /* 1697 Takes a few ticks to process button event because 1698 of debounce code of Mac. So have this mechanism 1699 to prevent processing further events meanwhile. 1700 */ 1701#endif 1702 1703GLOBALFUNC blnr FindKeyEvent(int *VirtualKey, blnr *KeyDown) 1704{ 1705 MyEvtQEl *p; 1706 1707 if ( 1708#if HaveMasterMyEvtQLock 1709 (0 == MasterMyEvtQLock) && 1710#endif 1711 (nullpr != (p = MyEvtQOutP()))) 1712 { 1713 if (MyEvtQElKindKey == p->kind) { 1714 *VirtualKey = p->u.press.key; 1715 *KeyDown = p->u.press.down; 1716 MyEvtQOutDone(); 1717 return trueblnr; 1718 } 1719 } 1720 1721 return falseblnr; 1722} 1723 1724/* task management */ 1725 1726#ifdef _VIA_Debug 1727#include <stdio.h> 1728#endif 1729 1730GLOBALVAR uimr ICTactive; 1731GLOBALVAR iCountt ICTwhen[kNumICTs]; 1732 1733GLOBALPROC ICT_Zap(void) 1734{ 1735 ICTactive = 0; 1736} 1737 1738LOCALPROC InsertICT(int taskid, iCountt when) 1739{ 1740 ICTwhen[taskid] = when; 1741 ICTactive |= (1 << taskid); 1742} 1743 1744GLOBALVAR iCountt NextiCount = 0; 1745 1746GLOBALFUNC iCountt GetCuriCount(void) 1747{ 1748 return NextiCount - GetCyclesRemaining(); 1749} 1750 1751GLOBALPROC ICT_add(int taskid, ui5b n) 1752{ 1753 /* n must be > 0 */ 1754 si5r x = GetCyclesRemaining(); 1755 ui5b when = NextiCount - x + n; 1756 1757#ifdef _VIA_Debug 1758 fprintf(stderr, "ICT_add: %d, %d, %d\n", when, taskid, n); 1759#endif 1760 InsertICT(taskid, when); 1761 1762 if (x > (si5r)n) { 1763 SetCyclesRemaining(n); 1764 NextiCount = when; 1765 } 1766}