this repo has no description
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}