1 // license:BSD-3-Clause
2 // copyright-holders:Nathan Woods, Raphael Nabet, R. Belmont
3 /****************************************************************************
4 
5     machine/mac.c
6 
7     Mac hardware - Mac 128k, 512k, 512ke, Plus, SE, Classic, II, PowerBook (SCSI, SCC, ADB, etc)
8 
9     Nate Woods
10     Ernesto Corvi
11     Raphael Nabet
12     R. Belmont
13 
14     Mac Model Feature Summary:
15                                 CPU             FDC     Kbd/Mouse  PRAM     Video
16          - Mac 128k             68k             IWM     orig       orig     Original
17          - Mac 512k             68k             IWM     orig       orig     Original
18          - Mac 512ke            68k             IWM     orig       orig     Original
19          - Mac Plus             68k             IWM     orig       ext      Original
20          - Mac SE               68k             IWM     MacII ADB  ext      Original
21          - Mac Classic          68k             SWIM    MacII ADB  ext      Original
22          - Mac Portable         68k (16 MHz)    SWIM    ADB-PMU    PMU      640x400 B&W
23          - PowerBook 100        68k (16 MHz)    SWIM    ADB-PMU    PMU      640x400 B&W
24          - Mac II               020             IWM     MacII ADB  ext      NuBus card
25          - Mac IIx              030             SWIM    MacII ADB  ext      NuBus card
26          - Mac IIfx             030             SWIM    IOP ADB    ext      NuBus card
27          - Mac SE/30            030             SWIM    MacII ADB  ext      Internal fake NuBus card
28          - Mac IIcx             030             SWIM    MacII ADB  ext      NuBus card
29          - Mac IIci             030             SWIM    MacII ADB  ext      Internal "RBV" type
30          - Mac IIsi             030             SWIM    Egret ADB  n/a      Internal "RBV" type
31          - PowerBook 140/145(B) 030 (16/25 MHz) SWIM    ADB-PMU    PMU      640x400 B&W (passive matrix)
32          - PowerBook 170        030 (25 MHz)    SWIM    ADB-PMU    PMU      640x400 B&W (active matrix)
33          - Mac IIvx/IIvi        030             SWIM    Egret ADB  n/a      Internal "VASP" type
34          - Mac LC               020             SWIM    Egret ADB  n/a      Internal "V8" type
35          - Mac LC II            030             SWIM    Egret ADB  n/a      Internal "V8" type
36          - Mac LC III           030             SWIM    Egret ADB  n/a      Internal "Sonora" type
37          - Mac Classic II       030             SWIM    Egret ADB  n/a      Internal "Eagle" type (V8 clone)
38          - Mac Color Classic    030             SWIM    Cuda ADB   n/a      Internal "Spice" type (V8 clone)
39          - Mac Quadra 700       040 (25 MHz)    SWIM II MacII ADB  ext      Internal "DAFB" type
40          - Mac Quadra 900       040 (33 MHz)    SWIM II IOP ADB    ext      Internal "DAFB" type
41 
42     Notes:
43         - The Mac Plus boot code seems to check to see the extent of ROM
44           mirroring to determine if SCSI is available.  If the ROM is mirrored,
45           then SCSI is not available.  Thanks to R. Belmont for making this
46           discovery.
47         - On the SE and most later Macs, the first access to ROM turns off the overlay.
48           However, the Mac II/IIx/IIcx (and others?) have the old-style VIA overlay control bit!
49         - The Mac II can have either a 68551 PMMU fitted or an Apple custom that handles 24 vs. 32
50           bit addressing mode.  The ROM is *not* 32-bit clean so Mac OS normally runs in 24 bit mode,
51           but A/UX can run 32.
52         - There are 5 known kinds of host-side ADB hardware:
53           * "Mac II ADB" used in the SE, II, IIx, IIcx, SE/30, IIci, Quadra 610, Quadra 650, Quadra 700,
54              Quadra 800, Centris 610 and Centris 650.  This is a bit-banger using the VIA and a simple PIC.
55           * "PMU ADB" used in the Mac Portable and all 680x0-based PowerBooks.
56           * "Egret ADB" used in the IIsi, IIvi, IIvx, Classic II, LC, LC II, LC III, Performa 460,
57              and Performa 600.  This is a 68HC05 with a different internal ROM than CUDA.
58           * "IOP ADB" (ADB driven by a 6502 coprocessor, similar to Lisa) used in the IIfx,
59             Quadra 900, and Quadra 950.
60           * "Cuda ADB" (Apple's CUDA chip, which is a 68HC05 MCU) used in the Color Classic, LC 520,
61             LC 55x, LC 57x, LC 58x, Quadra 630, Quadra 660AV, Quadra 840AV, PowerMac 6100/7100/8100,
62             IIci, and PowerMac 5200.
63 
64      TODO:
65         - Call the RTC timer
66 
67      Egret version spotting:
68      341S0850 - 0x???? (1.01, earlier) - LC, LC II
69      341S0851 - 0x0101 (1.01, later) - Classic II, IIsi, IIvx/IIvi, LC III
70      344S0100 - 0x0100 (1.00) - Some (early production?) IIsi
71 
72      Cuda version spotting:
73      341S0262 - 0x0003f200 (3.02) - some PMac 6500, Bondi blue iMac
74      341S0285 - No version (x.xx) - PMac 4400 + Mac clones ("Cuda Lite" with 768 bytes more ROM + PS/2 keyboard/mouse support)
75      341S0060 - 0x00020028 (2.40) - Performa/Quadra 6xx, PMac 6200, x400, some x500, Pippin, "Gossamer" G3, others?
76                                     (verified found in PMac 5500-225, G3-333)
77      341S0788 - 0x00020025 (2.37) - LC 475/575/Quadra 605, Quadra 660AV/840AV, PMac 7200
78      341S0417 - 0x00020023 (2.35) - Color Classic
79 
80      Caboose version spotting:
81      341S0853 - 0x0100 (1.00) - Quadra 950
82 
83      PG&E (68HC05 PMU) version spotting:
84      (find the text "BORG" in the system ROM, the next 32768 bytes are the PG&E image.
85       offset +4 in the image is the version byte).
86      01 - PowerBook Duo 210/230/250
87      02 - PowerBook 540c, PBDuo 270C, PBDuo 280/280C
88      03 - PowerBook 150
89      08 - PB190cs, PowerBook 540c PPC update, all PowerPC PowerBooks through WallStreet G3s
90 
91 ****************************************************************************/
92 
93 #include "emu.h"
94 #include "includes/mac.h"
95 #include "machine/sonydriv.h"
96 
97 #define AUDIO_IS_CLASSIC (m_model <= MODEL_MAC_CLASSIC)
98 #define MAC_HAS_VIA2    ((m_model >= MODEL_MAC_II) && (m_model != MODEL_MAC_IIFX))
99 
100 #define INTS_RBV    ((m_model >= MODEL_MAC_IICI) && (m_model <= MODEL_MAC_IIVI)) || ((m_model >= MODEL_MAC_LC) && (m_model <= MODEL_MAC_LC_580))
101 
102 #define MAC_MAIN_SND_BUF_OFFSET 0x0300
103 #define MAC_ALT_SND_BUF_OFFSET  0x5F00
104 
105 #ifdef MAME_DEBUG
106 #define LOG_ADB         0
107 #define LOG_VIA         0
108 #define LOG_MAC_IWM     0
109 #define LOG_GENERAL     0
110 #define LOG_KEYBOARD    0
111 #define LOG_MEMORY      0
112 #else
113 #define LOG_ADB         0
114 #define LOG_VIA         0
115 #define LOG_MAC_IWM     0
116 #define LOG_GENERAL     0
117 #define LOG_KEYBOARD    0
118 #define LOG_MEMORY      0
119 #endif
120 
121 // handle disk enable lines
mac_fdc_set_enable_lines(device_t * device,int enable_mask)122 void mac_fdc_set_enable_lines(device_t *device, int enable_mask)
123 {
124 	sony_set_enable_lines(device, enable_mask);
125 }
126 
mac_install_memory(offs_t memory_begin,offs_t memory_end,offs_t memory_size,void * memory_data,int is_rom,const char * bank)127 void mac_state::mac_install_memory(offs_t memory_begin, offs_t memory_end,
128 	offs_t memory_size, void *memory_data, int is_rom, const char *bank)
129 {
130 	address_space& space = m_maincpu->space(AS_PROGRAM);
131 	offs_t memory_mirror;
132 
133 	memory_size = std::min(memory_size, (memory_end + 1 - memory_begin));
134 	memory_mirror = (memory_end - memory_begin) & ~(memory_size - 1);
135 
136 	if (!is_rom)
137 	{
138 		space.install_readwrite_bank(memory_begin, memory_end & ~memory_mirror, memory_mirror, bank);
139 	}
140 	else
141 	{
142 		space.unmap_write(memory_begin, memory_end);
143 		space.install_read_bank(memory_begin, memory_end & ~memory_mirror, memory_mirror, bank);
144 	}
145 
146 	membank(bank)->set_base(memory_data);
147 
148 	if (LOG_MEMORY)
149 	{
150 		printf("mac_install_memory(): bank=%s range=[0x%06x...0x%06x] mirror=0x%06x ptr=0x%p\n",
151 			bank, memory_begin, memory_end, memory_mirror, memory_data);
152 	}
153 }
154 
155 
156 
157 /*
158     Interrupt handling
159 */
160 
field_interrupts()161 void mac_state::field_interrupts()
162 {
163 	int take_interrupt = -1;
164 
165 	if (m_model < MODEL_MAC_PORTABLE)
166 	{
167 		if ((m_scc_interrupt) || (m_scsi_interrupt))
168 		{
169 			take_interrupt = 2;
170 		}
171 		else if (m_via_interrupt)
172 		{
173 			take_interrupt = 1;
174 		}
175 	}
176 	else if ((m_model < MODEL_MAC_POWERMAC_6100) && (m_model != MODEL_MAC_IIFX))
177 	{
178 		if (m_scc_interrupt)
179 		{
180 			take_interrupt = 4;
181 		}
182 		else if (m_via2_interrupt)
183 		{
184 			take_interrupt = 2;
185 		}
186 		else if (m_via_interrupt)
187 		{
188 			take_interrupt = 1;
189 		}
190 	}
191 	else
192 	{
193 		return; // no interrupts for PowerPC yet
194 	}
195 
196 	if (m_last_taken_interrupt > -1)
197 	{
198 		m_maincpu->set_input_line(m_last_taken_interrupt, CLEAR_LINE);
199 		m_last_taken_interrupt = -1;
200 	}
201 
202 	if (take_interrupt > -1)
203 	{
204 		m_maincpu->set_input_line(take_interrupt, ASSERT_LINE);
205 		m_last_taken_interrupt = take_interrupt;
206 	}
207 }
208 
WRITE_LINE_MEMBER(mac_state::set_scc_interrupt)209 WRITE_LINE_MEMBER(mac_state::set_scc_interrupt)
210 {
211 	m_scc_interrupt = state;
212 	this->field_interrupts();
213 }
214 
set_via_interrupt(int value)215 void mac_state::set_via_interrupt(int value)
216 {
217 	m_via_interrupt = value;
218 	this->field_interrupts();
219 }
220 
221 
set_via2_interrupt(int value)222 void mac_state::set_via2_interrupt(int value)
223 {
224 	m_via2_interrupt = value;
225 	this->field_interrupts();
226 }
227 
WRITE_LINE_MEMBER(mac_state::mac_asc_irq)228 WRITE_LINE_MEMBER(mac_state::mac_asc_irq)
229 {
230 	if (INTS_RBV)
231 	{
232 		if (state == ASSERT_LINE)
233 		{
234 			m_rbv_regs[3] |= 0x10; // any VIA 2 interrupt | sound interrupt
235 			rbv_recalc_irqs();
236 		}
237 		else
238 		{
239 			m_rbv_regs[3] &= ~0x10;
240 			rbv_recalc_irqs();
241 		}
242 	}
243 	else if ((m_model >= MODEL_MAC_II) && (m_model != MODEL_MAC_IIFX))
244 	{
245 		m_via2->write_cb1(state^1);
246 	}
247 }
248 
mac_autovector_w(offs_t offset,uint16_t data)249 void mac_state::mac_autovector_w(offs_t offset, uint16_t data)
250 {
251 	if (LOG_GENERAL)
252 		logerror("mac_autovector_w: offset=0x%08x data=0x%04x\n", offset, data);
253 
254 	/* This should throw an exception */
255 
256 	/* Not yet implemented */
257 }
258 
mac_autovector_r(offs_t offset)259 uint16_t mac_state::mac_autovector_r(offs_t offset)
260 {
261 	if (LOG_GENERAL)
262 		logerror("mac_autovector_r: offset=0x%08x\n", offset);
263 
264 	/* This should throw an exception */
265 
266 	/* Not yet implemented */
267 	return 0;
268 }
269 
set_scc_waitrequest(int waitrequest)270 void mac_state::set_scc_waitrequest(int waitrequest)
271 {
272 	if (LOG_GENERAL)
273 		logerror("set_scc_waitrequest: waitrequest=%i\n", waitrequest);
274 
275 	/* Not Yet Implemented */
276 }
277 
v8_resize()278 void mac_state::v8_resize()
279 {
280 	offs_t memory_size;
281 	uint8_t *memory_data;
282 	int is_rom;
283 
284 	is_rom = (m_overlay) ? 1 : 0;
285 
286 	// get what memory we're going to map
287 	if (is_rom)
288 	{
289 		/* ROM mirror */
290 		memory_size = m_rom_size;
291 		memory_data = reinterpret_cast<uint8_t *>(m_rom_ptr);
292 		is_rom = true;
293 	}
294 	else
295 	{
296 		/* RAM */
297 		memory_size = m_ram->size();
298 		memory_data = m_ram->pointer();
299 		is_rom = false;
300 	}
301 
302 //    printf("mac_v8_resize: memory_size = %x, ctrl bits %02x (overlay %d = %s)\n", memory_size, m_rbv_regs[1] & 0xe0, m_overlay, is_rom ? "ROM" : "RAM");
303 
304 	if (is_rom)
305 	{
306 		mac_install_memory(0x00000000, memory_size-1, memory_size, memory_data, is_rom, "bank1");
307 
308 		// install catcher in place of ROM that will detect the first access to ROM in its real location
309 		m_maincpu->space(AS_PROGRAM).install_read_handler(0xa00000, 0xafffff, read32sm_delegate(*this, FUNC(mac_state::rom_switch_r)), 0xffffffff);
310 	}
311 	else
312 	{
313 		address_space& space = m_maincpu->space(AS_PROGRAM);
314 		uint32_t onboard_amt, simm_amt, simm_size;
315 		static const uint32_t simm_sizes[4] = { 0, 2*1024*1024, 4*1024*1024, 8*1024*1024 };
316 
317 		// re-install ROM in its normal place
318 		size_t rom_mirror = 0xfffff ^ (m_rom_size - 1);
319 		m_maincpu->space(AS_PROGRAM).install_read_bank(0xa00000, 0xafffff, rom_mirror, "bankR");
320 		membank("bankR")->set_base((void *)m_rom_ptr);
321 
322 		// force unmap of entire RAM region
323 		space.unmap_write(0, 0x9fffff);
324 
325 		// LC and Classic II have 2 MB built-in, all other V8-style machines have 4 MB
326 		// we reserve the first 2 or 4 MB of mess_ram for the onboard,
327 		// RAM above that mark is the SIMM
328 		onboard_amt = ((m_model == MODEL_MAC_LC) || (m_model == MODEL_MAC_CLASSIC_II)) ? 2*1024*1024 : 4*1024*1024;
329 		simm_amt = (m_rbv_regs[1]>>6) & 3;  // size of SIMM RAM window
330 		simm_size = memory_size - onboard_amt;  // actual amount of RAM available for SIMMs
331 
332 		// installing SIMM RAM?
333 		if (simm_amt != 0)
334 		{
335 //            printf("mac_v8_resize: SIMM region size is %x, SIMM size is %x, onboard size is %x\n", simm_sizes[simm_amt], simm_size, onboard_amt);
336 
337 			if ((simm_amt > 0) && (simm_size > 0))
338 			{
339 //              mac_install_memory(0x000000, simm_sizes[simm_amt]-1, simm_sizes[simm_amt], memory_data + onboard_amt, is_rom, "bank1");
340 				mac_install_memory(0x000000, simm_size-1, simm_size, memory_data + onboard_amt, is_rom, "bank1");
341 			}
342 
343 			// onboard RAM sits immediately above the SIMM, if any
344 			if (simm_sizes[simm_amt] + onboard_amt <= 0x800000)
345 			{
346 				mac_install_memory(simm_sizes[simm_amt], simm_sizes[simm_amt] + onboard_amt - 1, onboard_amt, memory_data, is_rom, "bank2");
347 			}
348 
349 			// a mirror of the first 2 MB of on board RAM always lives at 0x800000
350 			mac_install_memory(0x800000, 0x9fffff, 0x200000, memory_data, is_rom, "bank3");
351 		}
352 		else
353 		{
354 //          printf("mac_v8_resize: SIMM off, mobo RAM at 0 and top\n");
355 
356 			mac_install_memory(0x000000, onboard_amt-1, onboard_amt, memory_data, is_rom, "bank1");
357 			mac_install_memory(0x900000, 0x9fffff, 0x200000, memory_data+0x100000, is_rom, "bank3");
358 		}
359 	}
360 }
361 
set_memory_overlay(int overlay)362 void mac_state::set_memory_overlay(int overlay)
363 {
364 	offs_t memory_size;
365 	uint8_t *memory_data;
366 	int is_rom;
367 
368 	/* normalize overlay */
369 	overlay = overlay ? true : false;
370 
371 	if (overlay != m_overlay)
372 	{
373 		/* set up either main RAM area or ROM mirror at 0x000000-0x3fffff */
374 		if (overlay)
375 		{
376 			/* ROM mirror */
377 			memory_size = m_rom_size;
378 			memory_data = reinterpret_cast<uint8_t *>(m_rom_ptr);
379 			is_rom = true;
380 		}
381 		else
382 		{
383 			/* RAM */
384 			memory_size = m_ram->size();
385 			memory_data = m_ram->pointer();
386 			is_rom = false;
387 		}
388 
389 		/* install the memory */
390 		if (((m_model >= MODEL_MAC_LC) && (m_model <= MODEL_MAC_COLOR_CLASSIC) && ((m_model != MODEL_MAC_LC_III) && (m_model != MODEL_MAC_LC_III_PLUS))) || (m_model == MODEL_MAC_CLASSIC_II))
391 		{
392 			m_overlay = overlay;
393 			v8_resize();
394 		}
395 		else if ((m_model == MODEL_MAC_IICI) || (m_model == MODEL_MAC_IISI))
396 		{
397 			// ROM is OK to flood to 3fffffff
398 			if (is_rom)
399 			{
400 				mac_install_memory(0x00000000, 0x3fffffff, memory_size, memory_data, is_rom, "bank1");
401 			}
402 			else    // RAM: be careful not to populate ram B with a mirror or the ROM will get confused
403 			{
404 				mac_install_memory(0x00000000, memory_size-1, memory_size, memory_data, is_rom, "bank1");
405 				// switch ROM region to direct access instead of through rom_switch_r
406 				mac_install_memory(0x40000000, 0x4007ffff, memory_size, memory_data, is_rom, "bank2");
407 			}
408 		}
409 		else if (m_model == MODEL_MAC_IIFX)
410 		{
411 			address_space& space = m_maincpu->space(AS_PROGRAM);
412 			space.unmap_write(0x000000, 0x9fffff);
413 			mac_install_memory(0x000000, memory_size-1, memory_size, memory_data, is_rom, "bank1");
414 		}
415 		else if ((m_model == MODEL_MAC_PB140) || (m_model == MODEL_MAC_PB160) || ((m_model >= MODEL_MAC_PBDUO_210) && (m_model <= MODEL_MAC_PBDUO_270c)))
416 		{
417 			address_space& space = m_maincpu->space(AS_PROGRAM);
418 			space.unmap_write(0x000000, 0xffffff);
419 			mac_install_memory(0x000000, memory_size-1, memory_size, memory_data, is_rom, "bank1");
420 		}
421 		else if ((m_model >= MODEL_MAC_II) && (m_model <= MODEL_MAC_SE30) && (m_model != MODEL_MAC_IIVX) && (m_model != MODEL_MAC_IIVI))
422 		{
423 			mac_install_memory(0x00000000, 0x3fffffff, memory_size, memory_data, is_rom, "bank1");
424 		}
425 		else if ((m_model == MODEL_MAC_IIVX) || (m_model == MODEL_MAC_IIVI) || (m_model == MODEL_MAC_LC_III) || (m_model == MODEL_MAC_LC_III_PLUS) || (m_model >= MODEL_MAC_LC_475 && m_model <= MODEL_MAC_LC_580))   // up to 36 MB
426 		{
427 			mac_install_memory(0x00000000, memory_size-1, memory_size, memory_data, is_rom, "bank1");
428 
429 			if (is_rom)
430 			{
431 				m_maincpu->space(AS_PROGRAM).install_read_handler(0x40000000, 0x4fffffff, read32sm_delegate(*this, FUNC(mac_state::rom_switch_r)), 0xffffffff);
432 			}
433 			else
434 			{
435 				size_t rom_mirror = 0xfffffff ^ (m_rom_size - 1);
436 				m_maincpu->space(AS_PROGRAM).install_read_bank(0x40000000, 0x4fffffff & ~rom_mirror, rom_mirror, "bankR");
437 				membank("bankR")->set_base((void *)m_rom_ptr);
438 			}
439 		}
440 		else if (m_model == MODEL_MAC_QUADRA_700)
441 		{
442 			if (!is_rom)
443 			{
444 				mac_install_memory(0x40000000, 0x400fffff, m_rom_size, m_rom_ptr, true, "bank2");
445 			}
446 			mac_install_memory(0x00000000, memory_size-1, memory_size, memory_data, is_rom, "bank1");
447 		}
448 		else
449 		{
450 			mac_install_memory(0x00000000, 0x003fffff, memory_size, memory_data, is_rom, "bank1");
451 		}
452 
453 		m_overlay = overlay;
454 
455 		if (LOG_GENERAL)
456 			logerror("mac_set_memory_overlay: overlay=%i\n", overlay);
457 	}
458 }
459 
rom_switch_r(offs_t offset)460 uint32_t mac_state::rom_switch_r(offs_t offset)
461 {
462 	// disable the overlay
463 	if (m_overlay)
464 	{
465 		set_memory_overlay(0);
466 	}
467 
468 	//printf("rom_switch_r: offset %08x ROM_size -1 = %08x, masked = %08x\n", offset, m_rom_size-1, offset & ((m_rom_size - 1)>>2));
469 
470 	return m_rom_ptr[offset & ((m_rom_size - 1)>>2)];
471 }
472 
473 /* *************************************************************************
474  * SCSI
475  * *************************************************************************/
476 
477 /*
478 
479 From http://www.mac.m68k-linux.org/devel/plushw.php
480 
481 The address of each register is computed as follows:
482 
483   $580drn
484 
485   where r represents the register number (from 0 through 7),
486   n determines whether it a read or write operation
487   (0 for reads, or 1 for writes), and
488   d determines whether the DACK signal to the NCR 5380 is asserted.
489   (0 for not asserted, 1 is for asserted)
490 
491 Here's an example of the address expressed in binary:
492 
493   0101 1000 0000 00d0 0rrr 000n
494 
495 Note:  Asserting the DACK signal applies only to write operations to
496        the output data register and read operations from the input
497        data register.
498 
499   Symbolic            Memory
500   Location            Location   NCR 5380 Internal Register
501 
502   scsiWr+sODR+dackWr  $580201    Output Data Register with DACK
503   scsiWr+sODR         $580001    Output Data Register
504   scsiWr+sICR         $580011    Initiator Command Register
505   scsiWr+sMR          $580021    Mode Register
506   scsiWr+sTCR         $580031    Target Command Register
507   scsiWr+sSER         $580041    Select Enable Register
508   scsiWr+sDMAtx       $580051    Start DMA Send
509   scsiWr+sTDMArx      $580061    Start DMA Target Receive
510   scsiWr+sIDMArx      $580071    Start DMA Initiator Receive
511 
512   scsiRd+sIDR+dackRd  $580260    Current SCSI Data with DACK
513   scsiRd+sCDR         $580000    Current SCSI Data
514   scsiRd+sICR         $580010    Initiator Command Register
515   scsiRd+sMR          $580020    Mode Registor
516   scsiRd+sTCR         $580030    Target Command Register
517   scsiRd+sCSR         $580040    Current SCSI Bus Status
518   scsiRd+sBSR         $580050    Bus and Status Register
519   scsiRd+sIDR         $580060    Input Data Register
520   scsiRd+sRESET       $580070    Reset Parity/Interrupt
521              */
522 
macplus_scsi_r(offs_t offset,uint16_t mem_mask)523 uint16_t mac_state::macplus_scsi_r(offs_t offset, uint16_t mem_mask)
524 {
525 	int reg = (offset>>3) & 0xf;
526 
527 //  logerror("macplus_scsi_r: offset %x mask %x\n", offset, mem_mask);
528 
529 	if ((reg == 6) && (offset == 0x130))
530 	{
531 		reg = R5380_CURDATA_DTACK;
532 	}
533 
534 	return m_ncr5380->ncr5380_read_reg(reg)<<8;
535 }
536 
macii_scsi_drq_r(offs_t offset,uint32_t mem_mask)537 uint32_t mac_state::macii_scsi_drq_r(offs_t offset, uint32_t mem_mask)
538 {
539 	switch (mem_mask)
540 	{
541 		case 0xff000000:
542 			return m_ncr5380->ncr5380_read_reg(R5380_CURDATA_DTACK)<<24;
543 
544 		case 0xffff0000:
545 			return (m_ncr5380->ncr5380_read_reg(R5380_CURDATA_DTACK)<<24) | (m_ncr5380->ncr5380_read_reg(R5380_CURDATA_DTACK)<<16);
546 
547 		case 0xffffffff:
548 			return (m_ncr5380->ncr5380_read_reg(R5380_CURDATA_DTACK)<<24) | (m_ncr5380->ncr5380_read_reg(R5380_CURDATA_DTACK)<<16) | (m_ncr5380->ncr5380_read_reg(R5380_CURDATA_DTACK)<<8) | m_ncr5380->ncr5380_read_reg(R5380_CURDATA_DTACK);
549 
550 		default:
551 			logerror("macii_scsi_drq_r: unknown mem_mask %08x\n", mem_mask);
552 	}
553 
554 	return 0;
555 }
556 
macii_scsi_drq_w(offs_t offset,uint32_t data,uint32_t mem_mask)557 void mac_state::macii_scsi_drq_w(offs_t offset, uint32_t data, uint32_t mem_mask)
558 {
559 	switch (mem_mask)
560 	{
561 		case 0xff000000:
562 			m_ncr5380->ncr5380_write_reg(R5380_OUTDATA_DTACK, data>>24);
563 			break;
564 
565 		case 0xffff0000:
566 			m_ncr5380->ncr5380_write_reg(R5380_OUTDATA_DTACK, data>>24);
567 			m_ncr5380->ncr5380_write_reg(R5380_OUTDATA_DTACK, data>>16);
568 			break;
569 
570 		case 0xffffffff:
571 			m_ncr5380->ncr5380_write_reg(R5380_OUTDATA_DTACK, data>>24);
572 			m_ncr5380->ncr5380_write_reg(R5380_OUTDATA_DTACK, data>>16);
573 			m_ncr5380->ncr5380_write_reg(R5380_OUTDATA_DTACK, data>>8);
574 			m_ncr5380->ncr5380_write_reg(R5380_OUTDATA_DTACK, data&0xff);
575 			break;
576 
577 		default:
578 			logerror("macii_scsi_drq_w: unknown mem_mask %08x\n", mem_mask);
579 			break;
580 	}
581 }
582 
macplus_scsi_w(offs_t offset,uint16_t data,uint16_t mem_mask)583 void mac_state::macplus_scsi_w(offs_t offset, uint16_t data, uint16_t mem_mask)
584 {
585 	int reg = (offset>>3) & 0xf;
586 
587 //  logerror("macplus_scsi_w: data %x offset %x mask %x\n", data, offset, mem_mask);
588 
589 	if ((reg == 0) && (offset == 0x100))
590 	{
591 		reg = R5380_OUTDATA_DTACK;
592 	}
593 
594 	m_ncr5380->ncr5380_write_reg(reg, data);
595 }
596 
macii_scsi_w(offs_t offset,uint16_t data,uint16_t mem_mask)597 void mac_state::macii_scsi_w(offs_t offset, uint16_t data, uint16_t mem_mask)
598 {
599 	int reg = (offset>>3) & 0xf;
600 
601 //  logerror("macplus_scsi_w: data %x offset %x mask %x (PC=%x)\n", data, offset, mem_mask, m_maincpu->pc());
602 
603 	if ((reg == 0) && (offset == 0x100))
604 	{
605 		reg = R5380_OUTDATA_DTACK;
606 	}
607 
608 	m_ncr5380->ncr5380_write_reg(reg, data>>8);
609 }
610 
WRITE_LINE_MEMBER(mac_state::mac_scsi_irq)611 WRITE_LINE_MEMBER(mac_state::mac_scsi_irq)
612 {
613 /*  mac_state *mac = machine.driver_data<mac_state>();
614 
615     if ((mac->m_scsiirq_enable) && ((mac->m_model == MODEL_MAC_SE) || (mac->m_model == MODEL_MAC_CLASSIC)))
616     {
617         mac->m_scsi_interrupt = state;
618         mac->field_interrupts();
619     }*/
620 }
621 
622 /* *************************************************************************
623  * SCC
624  *
625  * Serial Communications Controller
626  * *************************************************************************/
mac_scc_r(offs_t offset)627 uint16_t mac_state::mac_scc_r(offs_t offset)
628 {
629 	uint16_t result;
630 
631 	result = m_scc->reg_r(offset);
632 	return (result << 8) | result;
633 }
634 
mac_scc_w(offs_t offset,uint16_t data)635 void mac_state::mac_scc_w(offs_t offset, uint16_t data)
636 {
637 	m_scc->reg_w(offset, data);
638 }
639 
mac_scc_2_w(offs_t offset,uint16_t data)640 void mac_state::mac_scc_2_w(offs_t offset, uint16_t data)
641 {
642 	m_scc->reg_w(offset, data >> 8);
643 }
644 
645 /* ********************************** *
646  * IWM Code specific to the Mac Plus  *
647  * ********************************** */
648 
mac_iwm_r(offs_t offset,uint16_t mem_mask)649 uint16_t mac_state::mac_iwm_r(offs_t offset, uint16_t mem_mask)
650 {
651 	/* The first time this is called is in a floppy test, which goes from
652 	 * $400104 to $400126.  After that, all access to the floppy goes through
653 	 * the disk driver in the MacOS
654 	 *
655 	 * I just thought this would be on interest to someone trying to further
656 	 * this driver along
657 	 */
658 
659 	uint16_t result = m_fdc->read(offset >> 8);
660 
661 	if (LOG_MAC_IWM)
662 		printf("%s mac_iwm_r: offset=0x%08x mem_mask %04x = %02x\n", machine().describe_context().c_str(), offset, mem_mask, result);
663 
664 	return (result << 8) | result;
665 }
666 
mac_iwm_w(offs_t offset,uint16_t data,uint16_t mem_mask)667 void mac_state::mac_iwm_w(offs_t offset, uint16_t data, uint16_t mem_mask)
668 {
669 	if (LOG_MAC_IWM)
670 		printf("mac_iwm_w: offset=0x%08x data=0x%04x mask %04x (PC=%x)\n", offset, data, mem_mask, m_maincpu->pc());
671 
672 	if (ACCESSING_BITS_0_7)
673 		m_fdc->write((offset >> 8), data & 0xff);
674 	else
675 		m_fdc->write((offset >> 8), data>>8);
676 }
677 
WRITE_LINE_MEMBER(mac_state::mac_adb_via_out_cb2)678 WRITE_LINE_MEMBER(mac_state::mac_adb_via_out_cb2)
679 {
680 	//printf("VIA OUT CB2 = %x\n", state);
681 	if (ADB_IS_EGRET)
682 	{
683 		m_egret->set_via_data(state & 1);
684 	}
685 	else if (ADB_IS_CUDA)
686 	{
687 		m_cuda->set_via_data(state & 1);
688 	}
689 	else
690 	{
691 		if (m_macadb)
692 		{
693 			m_macadb->adb_data_w(state);
694 		}
695 	}
696 }
697 
698 /* *************************************************************************
699  * VIA
700  * *************************************************************************
701  *
702  *
703  * PORT A
704  *
705  *  bit 7               R   SCC Wait/Request
706  *  bit 6               W   Main/Alternate screen buffer select
707  *  bit 5               W   Floppy Disk Line Selection
708  *  bit 4               W   Overlay/Normal memory mapping
709  *  bit 3               W   Main/Alternate sound buffer
710  *  bit 2-0             W   Sound Volume
711  *
712  *
713  * PORT B
714  *
715  *  bit 7               W   Sound enable
716  *  bit 6               R   Video beam in display
717  *  bit 5   (pre-ADB)   R   Mouse Y2
718  *          (ADB)       W   ADB ST1
719  *  bit 4   (pre-ADB)   R   Mouse X2
720  *          (ADB)       W   ADB ST0
721  *  bit 3   (pre-ADB)   R   Mouse button (active low)
722  *          (ADB)       R   ADB INT
723  *  bit 2               W   Real time clock enable
724  *  bit 1               W   Real time clock data clock
725  *  bit 0               RW  Real time clock data
726  *
727  */
728 
729 #define PA6 0x40
730 #define PA4 0x10
731 #define PA2 0x04
732 #define PA1 0x02
733 
mac_via_in_a()734 uint8_t mac_state::mac_via_in_a()
735 {
736 //  printf("%s VIA1 IN_A\n", machine().describe_context().c_str());
737 
738 	switch (m_model)
739 	{
740 		case MODEL_MAC_CLASSIC:
741 		case MODEL_MAC_II:
742 		case MODEL_MAC_II_FDHD:
743 		case MODEL_MAC_IIX:
744 		case MODEL_MAC_POWERMAC_6100:
745 		case MODEL_MAC_POWERMAC_7100:
746 		case MODEL_MAC_POWERMAC_8100:
747 			return 0x81;        // bit 0 must be set on most Macs to avoid attempting to boot from AppleTalk
748 
749 		case MODEL_MAC_SE30:
750 			return 0x81 | PA6;
751 
752 		case MODEL_MAC_LC:
753 		case MODEL_MAC_LC_II:
754 		case MODEL_MAC_IIVX:
755 		case MODEL_MAC_IIVI:
756 			return 0x81 | PA6 | PA4 | PA2;
757 
758 		case MODEL_MAC_IICI:
759 			return 0x81 | PA6 | PA2 | PA1;
760 
761 		case MODEL_MAC_IISI:
762 			return 0x81 | PA4 | PA2 | PA1;
763 
764 		case MODEL_MAC_IIFX:
765 			return 0x81 | PA6 | PA4 | PA1;
766 
767 		case MODEL_MAC_IICX:
768 			return 0x81 | PA6;
769 
770 		case MODEL_MAC_PB140:   // since the ASICs are different, these are allowed to "collide"
771 		case MODEL_MAC_PB160:
772 		case MODEL_MAC_CLASSIC_II:
773 		case MODEL_MAC_QUADRA_800:
774 			return 0x81 | PA4 | PA1;
775 
776 		case MODEL_MAC_QUADRA_700:
777 			return 0x81 | PA6;
778 
779 		case MODEL_MAC_QUADRA_900:
780 			return 0x81 | PA6 | PA4;
781 
782 		case MODEL_MAC_COLOR_CLASSIC:
783 			return 0x81 | PA1;
784 
785 		default:
786 			return 0x80;
787 	}
788 }
789 
mac_via_in_a_pmu()790 uint8_t mac_state::mac_via_in_a_pmu()
791 {
792 //  printf("%s VIA1 IN_A\n", machine().describe_context().c_str());
793 
794 	#if LOG_ADB
795 //  printf("Read PM data %x\n", m_pm_data_recv);
796 	#endif
797 	return m_macadb->get_pm_data_recv();
798 }
799 
mac_via_in_b()800 uint8_t mac_state::mac_via_in_b()
801 {
802 	int val = 0;
803 	/* video beam in display (! VBLANK && ! HBLANK basically) */
804 	if (m_screen->vpos() >= MAC_V_VIS)
805 		val |= 0x40;
806 
807 	if (ADB_IS_BITBANG_CLASS)
808 	{
809 		val |= m_macadb->get_adb_state()<<4;
810 
811 		if (!m_adb_irq_pending)
812 		{
813 			val |= 0x08;
814 		}
815 
816 		val |= m_rtc->data_r();
817 	}
818 	else if (ADB_IS_EGRET)
819 	{
820 		val |= m_egret->get_xcvr_session()<<3;
821 	}
822 	else if (ADB_IS_CUDA)
823 	{
824 		val |= m_cuda->get_treq()<<3;
825 	}
826 
827 //  printf("%s VIA1 IN_B = %02x\n", machine().describe_context().c_str(), val);
828 
829 	return val;
830 }
831 
mac_via_in_b_ii()832 uint8_t mac_state::mac_via_in_b_ii()
833 {
834 	int val = 0;
835 
836 	if (ADB_IS_BITBANG_CLASS)
837 	{
838 		val |= m_macadb->get_adb_state()<<4;
839 
840 		if (!m_adb_irq_pending)
841 		{
842 			val |= 0x08;
843 		}
844 
845 		val |= m_rtc->data_r();
846 	}
847 	else if (ADB_IS_EGRET)
848 	{
849 		val |= m_egret->get_xcvr_session()<<3;
850 	}
851 	else if (ADB_IS_CUDA)
852 	{
853 		val |= m_cuda->get_treq()<<3;
854 	}
855 
856 //  printf("%s VIA1 IN_B_II = %02x\n", machine().describe_context().c_str(), val);
857 
858 	return val;
859 }
860 
mac_via_in_b_via2pmu()861 uint8_t mac_state::mac_via_in_b_via2pmu()
862 {
863 	int val = 0;
864 	// TODO: is this valid for VIA2 PMU machines?
865 	/* video beam in display (! VBLANK && ! HBLANK basically) */
866 
867 	if (m_screen->vpos() >= MAC_V_VIS)
868 		val |= 0x40;
869 
870 
871 //  printf("%s VIA1 IN_B = %02x\n", machine().describe_context().c_str(), val);
872 
873 	return val;
874 }
875 
mac_via_in_b_pmu()876 uint8_t mac_state::mac_via_in_b_pmu()
877 {
878 	int val = 0;
879 //  printf("Read VIA B: PM_ACK %x\n", m_pm_ack);
880 	val = 0x80 | 0x04 | m_macadb->get_pm_ack();   // SCC wait/request (bit 2 must be set at 900c1a or startup tests always fail)
881 
882 //  printf("%s VIA1 IN_B = %02x\n", machine().describe_context().c_str(), val);
883 
884 	return val;
885 }
886 
mac_via_out_a(uint8_t data)887 void mac_state::mac_via_out_a(uint8_t data)
888 {
889 //  printf("%s VIA1 OUT A: %02x\n", machine().describe_context().c_str(), data);
890 
891 	set_scc_waitrequest((data & 0x80) >> 7);
892 	m_screen_buffer = (data & 0x40) >> 6;
893 	sony_set_sel_line(m_fdc.target(), (data & 0x20) >> 5);
894 }
895 
mac_via_out_a_pmu(uint8_t data)896 void mac_state::mac_via_out_a_pmu(uint8_t data)
897 {
898 //  printf("%s VIA1 OUT A: %02x\n", machine().describe_context().c_str(), data);
899 
900 	#if LOG_ADB
901 //  printf("%02x to PM\n", data);
902 	#endif
903 	m_macadb->set_pm_data_send(data);
904 }
905 
mac_via_out_b(uint8_t data)906 void mac_state::mac_via_out_b(uint8_t data)
907 {
908 //  printf("%s VIA1 OUT B: %02x\n", machine().describe_context().c_str(), data);
909 	m_rtc->ce_w((data & 0x04)>>2);
910 	m_rtc->data_w(data & 0x01);
911 	m_rtc->clk_w((data >> 1) & 0x01);
912 }
913 
mac_via_out_b_bbadb(uint8_t data)914 void mac_state::mac_via_out_b_bbadb(uint8_t data)
915 {
916 //  printf("%s VIA1 OUT B: %02x\n", machine().describe_context().c_str(), data);
917 
918 	if (m_model == MODEL_MAC_SE30)
919 	{
920 		// 0x40 = 0 means enable vblank on SE/30
921 		m_se30_vbl_enable = (data & 0x40) ? 0 : 1;
922 
923 		// clear the interrupt if we disabled it
924 		if (!m_se30_vbl_enable)
925 		{
926 			nubus_slot_interrupt(0xe, 0);
927 		}
928 	}
929 
930 	m_macadb->mac_adb_newaction((data & 0x30) >> 4);
931 
932 	m_rtc->ce_w((data & 0x04)>>2);
933 	m_rtc->data_w(data & 0x01);
934 	m_rtc->clk_w((data >> 1) & 0x01);
935 }
936 
mac_via_out_b_egadb(uint8_t data)937 void mac_state::mac_via_out_b_egadb(uint8_t data)
938 {
939 //  printf("%s VIA1 OUT B: %02x\n", machine().describe_context().c_str(), data);
940 
941 	#if LOG_ADB
942 	printf("%s 68K: New Egret state: SS %d VF %d\n", machine().describe_context().c_str(), (data>>5)&1, (data>>4)&1);
943 	#endif
944 	m_egret->set_via_full((data&0x10) ? 1 : 0);
945 	m_egret->set_sys_session((data&0x20) ? 1 : 0);
946 }
947 
mac_via_out_b_cdadb(uint8_t data)948 void mac_state::mac_via_out_b_cdadb(uint8_t data)
949 {
950 //  printf("%s VIA1 OUT B: %02x\n", machine().describe_context().c_str(), data);
951 
952 	#if LOG_ADB
953 	printf("%s 68K: New Cuda state: TIP %d BYTEACK %d\n", machine().describe_context().c_str(), (data>>5)&1, (data>>4)&1);
954 	#endif
955 	m_cuda->set_byteack((data&0x10) ? 1 : 0);
956 	m_cuda->set_tip((data&0x20) ? 1 : 0);
957 }
958 
mac_via_out_b_via2pmu(uint8_t data)959 void mac_state::mac_via_out_b_via2pmu(uint8_t data)
960 {
961 //  printf("%s VIA1 OUT B: %02x\n", machine().describe_context().c_str(), data);
962 }
963 
mac_via_out_b_pmu(uint8_t data)964 void mac_state::mac_via_out_b_pmu(uint8_t data)
965 {
966 //  printf("%s VIA1 OUT B: %02x\n", machine().describe_context().c_str(), data);
967 
968 	sony_set_sel_line(m_fdc.target(), (data & 0x20) >> 5);
969 	m_macadb->pmu_req_w(data & 1);
970 }
971 
WRITE_LINE_MEMBER(mac_state::mac_via_irq)972 WRITE_LINE_MEMBER(mac_state::mac_via_irq)
973 {
974 	/* interrupt the 68k (level 1) */
975 	set_via_interrupt(state);
976 }
977 
mac_via_r(offs_t offset)978 uint16_t mac_state::mac_via_r(offs_t offset)
979 {
980 	uint16_t data;
981 
982 	offset >>= 8;
983 	offset &= 0x0f;
984 
985 	if (LOG_VIA)
986 		logerror("mac_via_r: offset=0x%02x\n", offset);
987 	data = m_via1->read(offset);
988 
989 	m_maincpu->adjust_icount(m_via_cycles);
990 
991 	return (data & 0xff) | (data << 8);
992 }
993 
mac_via_w(offs_t offset,uint16_t data,uint16_t mem_mask)994 void mac_state::mac_via_w(offs_t offset, uint16_t data, uint16_t mem_mask)
995 {
996 	offset >>= 8;
997 	offset &= 0x0f;
998 
999 	if (LOG_VIA)
1000 		logerror("mac_via_w: offset=0x%02x data=0x%08x\n", offset, data);
1001 
1002 	if (ACCESSING_BITS_0_7)
1003 		m_via1->write(offset, data & 0xff);
1004 	if (ACCESSING_BITS_8_15)
1005 		m_via1->write(offset, (data >> 8) & 0xff);
1006 
1007 	m_maincpu->adjust_icount(m_via_cycles);
1008 }
1009 
1010 /* *************************************************************************
1011  * VIA 2 (on Mac IIs, PowerBooks > 100, and PowerMacs)
1012  * *************************************************************************/
1013 
WRITE_LINE_MEMBER(mac_state::mac_via2_irq)1014 WRITE_LINE_MEMBER(mac_state::mac_via2_irq)
1015 {
1016 	set_via2_interrupt(state);
1017 }
1018 
mac_via2_r(offs_t offset)1019 uint16_t mac_state::mac_via2_r(offs_t offset)
1020 {
1021 	int data;
1022 
1023 	offset >>= 8;
1024 	offset &= 0x0f;
1025 
1026 	data = m_via2->read(offset);
1027 
1028 	if (LOG_VIA)
1029 		logerror("mac_via2_r: offset=0x%02x = %02x (PC=%x)\n", offset*2, data, m_maincpu->pc());
1030 
1031 	return (data & 0xff) | (data << 8);
1032 }
1033 
mac_via2_w(offs_t offset,uint16_t data,uint16_t mem_mask)1034 void mac_state::mac_via2_w(offs_t offset, uint16_t data, uint16_t mem_mask)
1035 {
1036 	offset >>= 8;
1037 	offset &= 0x0f;
1038 
1039 	if (LOG_VIA)
1040 		logerror("mac_via2_w: offset=%x data=0x%08x mask=%x (PC=%x)\n", offset, data, mem_mask, m_maincpu->pc());
1041 
1042 	if (ACCESSING_BITS_0_7)
1043 		m_via2->write(offset, data & 0xff);
1044 	if (ACCESSING_BITS_8_15)
1045 		m_via2->write(offset, (data >> 8) & 0xff);
1046 }
1047 
1048 
mac_via2_in_a()1049 uint8_t mac_state::mac_via2_in_a()
1050 {
1051 	uint8_t result;
1052 
1053 	if ((m_model == MODEL_MAC_QUADRA_900) || (m_model == MODEL_MAC_QUADRA_950))
1054 	{
1055 		result = 0x80 | m_nubus_irq_state;
1056 	}
1057 	else
1058 	{
1059 		result = 0xc0 | m_nubus_irq_state;
1060 	}
1061 
1062 	return result;
1063 }
1064 
mac_via2_in_a_pmu()1065 uint8_t mac_state::mac_via2_in_a_pmu()
1066 {
1067 	return m_macadb->get_pm_data_recv();
1068 }
1069 
mac_via2_in_b()1070 uint8_t mac_state::mac_via2_in_b()
1071 {
1072 //  logerror("%s VIA2 IN B\n", machine().describe_context());
1073 
1074 	if ((m_model == MODEL_MAC_LC) || (m_model == MODEL_MAC_LC_II) || (m_model == MODEL_MAC_CLASSIC_II))
1075 	{
1076 		return 0x4f;
1077 	}
1078 
1079 	if ((m_model == MODEL_MAC_SE30) || (m_model == MODEL_MAC_IIX))
1080 	{
1081 		return 0x87;    // bits 3 and 6 are tied low on SE/30
1082 	}
1083 
1084 	return 0xcf;        // indicate no NuBus transaction error
1085 }
1086 
mac_via2_in_b_pmu()1087 uint8_t mac_state::mac_via2_in_b_pmu()
1088 {
1089 //  logerror("%s VIA2 IN B\n", machine().describe_context());
1090 
1091 	if (m_macadb->get_pm_ack() == 2)
1092 	{
1093 		return 0xcf;
1094 	}
1095 	else
1096 	{
1097 		return 0xcd;
1098 	}
1099 }
1100 
mac_via2_out_a(uint8_t data)1101 void mac_state::mac_via2_out_a(uint8_t data)
1102 {
1103 //  logerror("%s VIA2 OUT A: %02x\n", machine().describe_context(), data);
1104 }
1105 
mac_via2_out_a_pmu(uint8_t data)1106 void mac_state::mac_via2_out_a_pmu(uint8_t data)
1107 {
1108 //  logerror("%s VIA2 OUT A: %02x\n", machine().describe_context(), data);
1109 	m_macadb->set_pm_data_send(data);
1110 }
1111 
mac_via2_out_b(uint8_t data)1112 void mac_state::mac_via2_out_b(uint8_t data)
1113 {
1114 //  logerror("%s VIA2 OUT B: %02x\n", machine().describe_context(), data);
1115 
1116 	// chain 60.15 Hz to VIA1
1117 	m_via1->write_ca1(data>>7);
1118 
1119 	if (m_model == MODEL_MAC_II)
1120 	{
1121 		m68000_base_device *m68k = downcast<m68000_base_device *>(m_maincpu.target());
1122 		m68k->set_hmmu_enable((data & 0x8) ? M68K_HMMU_DISABLE : M68K_HMMU_ENABLE_II);
1123 	}
1124 }
1125 
mac_via2_out_b_pmu(uint8_t data)1126 void mac_state::mac_via2_out_b_pmu(uint8_t data)
1127 {
1128 //  logerror("%s VIA2 OUT B PMU: %02x\n", machine().describe_context(), data);
1129 	m_macadb->pmu_req_w((data>>2) & 1);
1130 }
1131 
1132 // This signal is generated internally on RBV, V8, Sonora, VASP, Eagle, etc.
TIMER_CALLBACK_MEMBER(mac_state::mac_6015_tick)1133 TIMER_CALLBACK_MEMBER(mac_state::mac_6015_tick)
1134 {
1135 	m_via1->write_ca1(0);
1136 	m_via1->write_ca1(1);
1137 }
1138 
1139 /* *************************************************************************
1140  * Main
1141  * *************************************************************************/
1142 
machine_start()1143 void mac_state::machine_start()
1144 {
1145 	if (m_screen)
1146 	{
1147 		this->m_scanline_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mac_state::mac_scanline_tick),this));
1148 		this->m_scanline_timer->adjust(m_screen->time_until_pos(0, 0));
1149 	}
1150 	else
1151 	{
1152 		m_adbupdate_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mac_state::mac_adbrefresh_tick),this));
1153 		m_adbupdate_timer->adjust(attotime::from_hz(70));
1154 	}
1155 
1156 	m_6015_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mac_state::mac_6015_tick),this));
1157 	m_6015_timer->adjust(attotime::never);
1158 }
1159 
machine_reset()1160 void mac_state::machine_reset()
1161 {
1162 	if ((ADB_IS_EGRET) || (ADB_IS_CUDA))
1163 	{
1164 		m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
1165 	}
1166 
1167 	// stop 60.15 Hz timer
1168 	m_6015_timer->adjust(attotime::never);
1169 
1170 	m_rbv_vbltime = 0;
1171 
1172 	if (m_model >= MODEL_MAC_POWERMAC_6100 && m_model <= MODEL_MAC_POWERMAC_8100)
1173 	{
1174 		m_awacs->set_dma_base(m_maincpu->space(AS_PROGRAM), 0x10000, 0x12000);
1175 	}
1176 
1177 	// start 60.15 Hz timer for most systems
1178 	if (((m_model >= MODEL_MAC_IICI) && (m_model <= MODEL_MAC_IIVI)) || (m_model >= MODEL_MAC_LC))
1179 	{
1180 		m_6015_timer->adjust(attotime::from_hz(60.15), 0, attotime::from_hz(60.15));
1181 	}
1182 
1183 	// we use the CPU clock divided by the VIA clock (783360 Hz) rounded up as
1184 	// an approximation for the right number of wait states.  this yields good
1185 	// results - it's towards the end of the worst-case delay on h/w.
1186 	switch (m_maincpu->clock())
1187 	{
1188 		case 7833600:   // C7M on classic Macs
1189 			m_via_cycles = -10;
1190 			break;
1191 
1192 		case 7833600*2: // "16 MHz" Macs
1193 			m_via_cycles = -32;
1194 			break;
1195 
1196 		case 20000000:  // 20 MHz Macs
1197 			m_via_cycles = -40;
1198 			break;
1199 
1200 		case 25000000:  // 25 MHz Macs
1201 			m_via_cycles = -50;
1202 			break;
1203 
1204 		case 7833600*4: // 32 MHz Macs (these are C7M * 4 like IIvx)
1205 			m_via_cycles = -62;
1206 			break;
1207 
1208 		case 33000000:  // 33 MHz Macs ('040s)
1209 			m_via_cycles = -64;
1210 			break;
1211 
1212 		case 40000000:  // 40 MHz Macs
1213 			m_via_cycles = -80;
1214 			break;
1215 
1216 		case 60000000:  // 60 MHz PowerMac
1217 			m_via_cycles = -120;
1218 			break;
1219 
1220 		case 66000000:  // 66 MHz PowerMac
1221 			m_via_cycles = -128;
1222 			break;
1223 
1224 		default:
1225 			fatalerror("mac: unknown clock\n");
1226 	}
1227 
1228 	// Egret currently needs more dramatic VIA slowdowns.  Need to determine what's realistic.
1229 	if (ADB_IS_EGRET)
1230 	{
1231 		m_via_cycles *= 35;
1232 	}
1233 
1234 	// default to 32-bit mode on LC
1235 	if (m_model == MODEL_MAC_LC)
1236 	{
1237 		m68000_base_device *m68k = downcast<m68000_base_device *>(m_maincpu.target());
1238 		m68k->set_hmmu_enable(M68K_HMMU_DISABLE);
1239 	}
1240 
1241 	m_last_taken_interrupt = -1;
1242 
1243 	/* setup the memory overlay */
1244 	if (m_model < MODEL_MAC_POWERMAC_6100)  // no overlay for PowerPC
1245 	{
1246 		m_overlay = -1; // insure no match
1247 		this->set_memory_overlay(1);
1248 	}
1249 
1250 	if (m_overlay_timeout != (emu_timer *)nullptr)
1251 	{
1252 		if ((m_model == MODEL_MAC_LC_III) || (m_model == MODEL_MAC_LC_III_PLUS) || (m_model >= MODEL_MAC_LC_475 && m_model <= MODEL_MAC_LC_580))   // up to 36 MB
1253 		{
1254 			m_overlay_timeout->adjust(attotime::never);
1255 		}
1256 		else if (((m_model >= MODEL_MAC_LC) && (m_model <= MODEL_MAC_COLOR_CLASSIC) && ((m_model != MODEL_MAC_LC_III) && (m_model != MODEL_MAC_LC_III_PLUS))) || (m_model == MODEL_MAC_CLASSIC_II))
1257 		{
1258 			m_overlay_timeout->adjust(attotime::never);
1259 		}
1260 		else if ((m_model >= MODEL_MAC_IIVX) && (m_model <= MODEL_MAC_IIVI))
1261 		{
1262 			m_overlay_timeout->adjust(attotime::never);
1263 		}
1264 		else
1265 		{
1266 			m_overlay_timeout->adjust(m_maincpu->cycles_to_attotime(8));
1267 		}
1268 	}
1269 
1270 	/* setup videoram */
1271 	this->m_screen_buffer = 1;
1272 
1273 	if (MAC_HAS_VIA2)  // prime CB1 for ASC and slot interrupts
1274 	{
1275 		m_via2_ca1_hack = 1;
1276 		m_via2->write_ca1(1);
1277 		m_via2->write_cb1(1);
1278 	}
1279 
1280 	m_scsi_interrupt = 0;
1281 
1282 	m_via2_vbl = 0;
1283 	m_se30_vbl_enable = 0;
1284 	m_nubus_irq_state = 0xff;
1285 	m_last_taken_interrupt = 0;
1286 }
1287 
WRITE_LINE_MEMBER(mac_state::cuda_reset_w)1288 WRITE_LINE_MEMBER(mac_state::cuda_reset_w)
1289 {
1290 	if ((state == ASSERT_LINE) && (m_model < MODEL_MAC_POWERMAC_6100))
1291 	{
1292 		set_memory_overlay(0);
1293 		set_memory_overlay(1);
1294 	}
1295 
1296 	m_maincpu->set_input_line(INPUT_LINE_HALT, state);
1297 	m_maincpu->set_input_line(INPUT_LINE_RESET, state);
1298 }
1299 
mac_state_load()1300 void mac_state::mac_state_load()
1301 {
1302 	int overlay;
1303 	overlay = m_overlay;
1304 	if (m_model < MODEL_MAC_POWERMAC_6100) // no overlay for PowerPC
1305 	{
1306 		m_overlay = -1;
1307 		set_memory_overlay(overlay);
1308 	}
1309 }
1310 
1311 
TIMER_CALLBACK_MEMBER(mac_state::overlay_timeout_func)1312 TIMER_CALLBACK_MEMBER(mac_state::overlay_timeout_func)
1313 {
1314 	if (m_overlay != -1)
1315 	{
1316 		set_memory_overlay(0);      // kill the overlay
1317 	}
1318 
1319 	// we're a one-time-only thing
1320 	m_overlay_timeout->adjust(attotime::never);
1321 }
1322 
mac_read_id()1323 uint32_t mac_state::mac_read_id()
1324 {
1325 //    printf("Mac read ID reg @ PC=%x\n", m_maincpu->pc());
1326 
1327 	switch (m_model)
1328 	{
1329 		case MODEL_MAC_LC_III:
1330 			return 0xa55a0001;  // 25 MHz LC III
1331 
1332 		case MODEL_MAC_LC_III_PLUS:
1333 			return 0xa55a0003;  // 33 MHz LC III+
1334 
1335 		case MODEL_MAC_LC_475:
1336 			return 0xa55a2221;
1337 
1338 		case MODEL_MAC_LC_520:
1339 			return 0xa55a0100;
1340 
1341 		case MODEL_MAC_LC_550:
1342 			return 0xa55a0101;
1343 
1344 		case MODEL_MAC_LC_575:
1345 			return 0xa55a222e;
1346 
1347 		case MODEL_MAC_POWERMAC_6100:
1348 			return 0xa55a3011;
1349 
1350 		case MODEL_MAC_POWERMAC_7100:
1351 			return 0xa55a3012;
1352 
1353 		case MODEL_MAC_POWERMAC_8100:
1354 			return 0xa55a3013;
1355 
1356 		case MODEL_MAC_PBDUO_210:
1357 			return 0xa55a1004;
1358 
1359 		case MODEL_MAC_PBDUO_230:
1360 			return 0xa55a1005;
1361 
1362 		case MODEL_MAC_PBDUO_250:
1363 			return 0xa55a1006;
1364 
1365 		case MODEL_MAC_QUADRA_605:
1366 			return 0xa55a2225;
1367 
1368 		case MODEL_MAC_QUADRA_610:
1369 		case MODEL_MAC_QUADRA_650:
1370 		case MODEL_MAC_QUADRA_800:
1371 			return 0xa55a2bad;
1372 
1373 		case MODEL_MAC_QUADRA_660AV:
1374 		case MODEL_MAC_QUADRA_840AV:
1375 			return 0xa55a2830;
1376 
1377 		case MODEL_MAC_IIVX:
1378 			return 0xa55a2015;
1379 
1380 		default:
1381 			return 0;
1382 	}
1383 }
1384 
mac_driver_init(model_t model)1385 void mac_state::mac_driver_init(model_t model)
1386 {
1387 	m_overlay = 1;
1388 	m_scsi_interrupt = 0;
1389 	m_model = model;
1390 
1391 	m_rom_size = memregion("bootrom")->bytes();
1392 	m_rom_ptr = reinterpret_cast<uint32_t *>(memregion("bootrom")->base());
1393 
1394 	if (model < MODEL_MAC_PORTABLE)
1395 	{
1396 		/* set up RAM mirror at 0x600000-0x6fffff (0x7fffff ???) */
1397 		mac_install_memory(0x600000, 0x6fffff, m_ram->size(), m_ram->pointer(), false, "bank2");
1398 
1399 		/* set up ROM at 0x400000-0x4fffff (-0x5fffff for mac 128k/512k/512ke) */
1400 		mac_install_memory(0x400000, (model >= MODEL_MAC_PLUS) ? 0x4fffff : 0x5fffff,
1401 			m_rom_size, m_rom_ptr, true, "bank3");
1402 	}
1403 
1404 	m_overlay = -1;
1405 	if (m_model < MODEL_MAC_POWERMAC_6100) // no overlay for PowerPC
1406 	{
1407 		set_memory_overlay(1);
1408 	}
1409 
1410 	memset(m_ram->pointer(), 0, m_ram->size());
1411 
1412 	if ((model == MODEL_MAC_SE) || (model == MODEL_MAC_CLASSIC) || (model == MODEL_MAC_CLASSIC_II) || (model == MODEL_MAC_LC) || (model == MODEL_MAC_COLOR_CLASSIC) || (model >= MODEL_MAC_LC_475 && model <= MODEL_MAC_LC_580) ||
1413 		(model == MODEL_MAC_LC_II) || (model == MODEL_MAC_LC_III) || (model == MODEL_MAC_LC_III_PLUS) || ((m_model >= MODEL_MAC_II) && (m_model <= MODEL_MAC_SE30)))
1414 	{
1415 		m_overlay_timeout = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mac_state::overlay_timeout_func),this));
1416 	}
1417 	else
1418 	{
1419 		m_overlay_timeout = (emu_timer *)nullptr;
1420 	}
1421 
1422 	/* save state stuff */
1423 	machine().save().register_postload(save_prepost_delegate(FUNC(mac_state::mac_state_load), this));
1424 }
1425 
1426 #define MAC_DRIVER_INIT(label, model)   \
1427 void mac_state::init_##label()     \
1428 {   \
1429 	mac_driver_init(model); \
1430 }
1431 
MAC_DRIVER_INIT(macse,MODEL_MAC_SE)1432 MAC_DRIVER_INIT(macse, MODEL_MAC_SE)
1433 MAC_DRIVER_INIT(macclassic, MODEL_MAC_CLASSIC)
1434 MAC_DRIVER_INIT(maclc, MODEL_MAC_LC)
1435 MAC_DRIVER_INIT(maclc2, MODEL_MAC_LC_II)
1436 MAC_DRIVER_INIT(maclc3, MODEL_MAC_LC_III)
1437 MAC_DRIVER_INIT(maclc3plus, MODEL_MAC_LC_III_PLUS)
1438 MAC_DRIVER_INIT(maciici, MODEL_MAC_IICI)
1439 MAC_DRIVER_INIT(maciisi, MODEL_MAC_IISI)
1440 MAC_DRIVER_INIT(macii, MODEL_MAC_II)
1441 MAC_DRIVER_INIT(macse30, MODEL_MAC_SE30)
1442 MAC_DRIVER_INIT(macclassic2, MODEL_MAC_CLASSIC_II)
1443 MAC_DRIVER_INIT(maclrcclassic, MODEL_MAC_COLOR_CLASSIC)
1444 MAC_DRIVER_INIT(macpm6100, MODEL_MAC_POWERMAC_6100)
1445 MAC_DRIVER_INIT(macpm7100, MODEL_MAC_POWERMAC_7100)
1446 MAC_DRIVER_INIT(macpm8100, MODEL_MAC_POWERMAC_8100)
1447 MAC_DRIVER_INIT(maciivx, MODEL_MAC_IIVX)
1448 MAC_DRIVER_INIT(maciivi, MODEL_MAC_IIVI)
1449 MAC_DRIVER_INIT(maciifx, MODEL_MAC_IIFX)
1450 MAC_DRIVER_INIT(maciicx, MODEL_MAC_IICX)
1451 MAC_DRIVER_INIT(maciifdhd, MODEL_MAC_II_FDHD)
1452 MAC_DRIVER_INIT(maciix, MODEL_MAC_IIX)
1453 MAC_DRIVER_INIT(maclc520, MODEL_MAC_LC_520)
1454 
1455 void mac_state::nubus_slot_interrupt(uint8_t slot, uint32_t state)
1456 {
1457 	static const uint8_t masks[8] = { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 };
1458 	uint8_t mask = 0x3f;
1459 
1460 	slot -= 9;
1461 
1462 	if (state)
1463 	{
1464 		m_nubus_irq_state &= ~masks[slot];
1465 	}
1466 	else
1467 	{
1468 		m_nubus_irq_state |= masks[slot];
1469 	}
1470 
1471 	if ((m_model != MODEL_MAC_IIFX) && (!INTS_RBV))
1472 	{
1473 		if ((m_nubus_irq_state & mask) != mask)
1474 		{
1475 			// HACK: sometimes we miss an ack (possible misbehavior in the VIA?)
1476 			if (m_via2_ca1_hack == 0)
1477 			{
1478 				m_via2->write_ca1(1);
1479 			}
1480 			m_via2_ca1_hack = 0;
1481 			m_via2->write_ca1(0);
1482 		}
1483 		else
1484 		{
1485 			m_via2_ca1_hack = 1;
1486 			m_via2->write_ca1(1);
1487 		}
1488 	}
1489 
1490 	if (INTS_RBV)
1491 	{
1492 		m_rbv_regs[2] &= ~0x38;
1493 		m_rbv_regs[2] |= (m_nubus_irq_state & 0x38);
1494 		rbv_recalc_irqs();
1495 	}
1496 }
1497 
vblank_irq()1498 void mac_state::vblank_irq()
1499 {
1500 	/* handle ADB keyboard/mouse */
1501 	if (has_adb() && m_macadb)
1502 	{
1503 		m_macadb->adb_vblank();
1504 	}
1505 
1506 	/* signal VBlank on CA1 input on the VIA */
1507 	if ((m_model < MODEL_MAC_II) || (m_model == MODEL_MAC_PB140) || (m_model == MODEL_MAC_PB160) || (m_model == MODEL_MAC_QUADRA_700))
1508 	{
1509 		ca1_data ^= 1;
1510 		m_via1->write_ca1(ca1_data);
1511 	}
1512 
1513 	if (++irq_count == 60)
1514 	{
1515 		irq_count = 0;
1516 
1517 		ca2_data ^= 1;
1518 		/* signal 1 Hz irq on CA2 input on the VIA */
1519 		m_via1->write_ca2(ca2_data);
1520 	}
1521 
1522 	// handle SE/30 vblank IRQ
1523 	if (m_model == MODEL_MAC_SE30)
1524 	{
1525 		if (m_se30_vbl_enable)
1526 		{
1527 			m_via2_vbl ^= 1;
1528 			if (!m_via2_vbl)
1529 			{
1530 				this->nubus_slot_interrupt(0xe, 1);
1531 			}
1532 		}
1533 	}
1534 }
1535 
TIMER_CALLBACK_MEMBER(mac_state::mac_adbrefresh_tick)1536 TIMER_CALLBACK_MEMBER(mac_state::mac_adbrefresh_tick)
1537 {
1538 	vblank_irq();
1539 	m_adbupdate_timer->adjust(attotime::from_hz(70));
1540 }
1541 
TIMER_CALLBACK_MEMBER(mac_state::mac_scanline_tick)1542 TIMER_CALLBACK_MEMBER(mac_state::mac_scanline_tick)
1543 {
1544 	int scanline;
1545 
1546 	if (m_rbv_vbltime > 0)
1547 	{
1548 		m_rbv_vbltime--;
1549 
1550 		if (m_rbv_vbltime == 0)
1551 		{
1552 			m_rbv_regs[2] |= 0x40;
1553 			rbv_recalc_irqs();
1554 		}
1555 	}
1556 
1557 	scanline = m_screen->vpos();
1558 	if (scanline == MAC_V_VIS)
1559 		vblank_irq();
1560 
1561 	int next_scanline = (scanline+1) % MAC_V_TOTAL;
1562 	m_scanline_timer->adjust(m_screen->time_until_pos(next_scanline), next_scanline);
1563 }
1564 
WRITE_LINE_MEMBER(mac_state::nubus_irq_9_w)1565 WRITE_LINE_MEMBER(mac_state::nubus_irq_9_w)
1566 {
1567 	nubus_slot_interrupt(9, state);
1568 }
1569 
WRITE_LINE_MEMBER(mac_state::nubus_irq_a_w)1570 WRITE_LINE_MEMBER(mac_state::nubus_irq_a_w)
1571 {
1572 	nubus_slot_interrupt(0xa, state);
1573 }
1574 
WRITE_LINE_MEMBER(mac_state::nubus_irq_b_w)1575 WRITE_LINE_MEMBER(mac_state::nubus_irq_b_w)
1576 {
1577 	nubus_slot_interrupt(0xb, state);
1578 }
1579 
WRITE_LINE_MEMBER(mac_state::nubus_irq_c_w)1580 WRITE_LINE_MEMBER(mac_state::nubus_irq_c_w)
1581 {
1582 	nubus_slot_interrupt(0xc, state);
1583 }
1584 
WRITE_LINE_MEMBER(mac_state::nubus_irq_d_w)1585 WRITE_LINE_MEMBER(mac_state::nubus_irq_d_w)
1586 {
1587 	nubus_slot_interrupt(0xd, state);
1588 }
1589 
WRITE_LINE_MEMBER(mac_state::nubus_irq_e_w)1590 WRITE_LINE_MEMBER(mac_state::nubus_irq_e_w)
1591 {
1592 	nubus_slot_interrupt(0xe, state);
1593 }
1594 
1595 /* *************************************************************************
1596  * Trap Tracing
1597  *
1598  * This is debug code that will output diagnostics regarding OS traps called
1599  * *************************************************************************/
1600 
lookup_trap(uint16_t opcode)1601 const char *lookup_trap(uint16_t opcode)
1602 {
1603 	static const struct
1604 	{
1605 		uint16_t trap;
1606 		const char *name;
1607 	} traps[] =
1608 	{
1609 		{ 0xA000, "_Open" },
1610 		{ 0xA001, "_Close" },
1611 		{ 0xA002, "_Read" },
1612 		{ 0xA003, "_Write" },
1613 		{ 0xA004, "_Control" },
1614 		{ 0xA005, "_Status" },
1615 		{ 0xA006, "_KillIO" },
1616 		{ 0xA007, "_GetVolInfo" },
1617 		{ 0xA008, "_Create" },
1618 		{ 0xA009, "_Delete" },
1619 		{ 0xA00A, "_OpenRF" },
1620 		{ 0xA00B, "_Rename" },
1621 		{ 0xA00C, "_GetFileInfo" },
1622 		{ 0xA00D, "_SetFileInfo" },
1623 		{ 0xA00E, "_UnmountVol" },
1624 		{ 0xA00F, "_MountVol" },
1625 		{ 0xA010, "_Allocate" },
1626 		{ 0xA011, "_GetEOF" },
1627 		{ 0xA012, "_SetEOF" },
1628 		{ 0xA013, "_FlushVol" },
1629 		{ 0xA014, "_GetVol" },
1630 		{ 0xA015, "_SetVol" },
1631 		{ 0xA016, "_FInitQueue" },
1632 		{ 0xA017, "_Eject" },
1633 		{ 0xA018, "_GetFPos" },
1634 		{ 0xA019, "_InitZone" },
1635 		{ 0xA01B, "_SetZone" },
1636 		{ 0xA01C, "_FreeMem" },
1637 		{ 0xA01F, "_DisposePtr" },
1638 		{ 0xA020, "_SetPtrSize" },
1639 		{ 0xA021, "_GetPtrSize" },
1640 		{ 0xA023, "_DisposeHandle" },
1641 		{ 0xA024, "_SetHandleSize" },
1642 		{ 0xA025, "_GetHandleSize" },
1643 		{ 0xA027, "_ReallocHandle" },
1644 		{ 0xA029, "_HLock" },
1645 		{ 0xA02A, "_HUnlock" },
1646 		{ 0xA02B, "_EmptyHandle" },
1647 		{ 0xA02C, "_InitApplZone" },
1648 		{ 0xA02D, "_SetApplLimit" },
1649 		{ 0xA02E, "_BlockMove" },
1650 		{ 0xA02F, "_PostEvent" },
1651 		{ 0xA030, "_OSEventAvail" },
1652 		{ 0xA031, "_GetOSEvent" },
1653 		{ 0xA032, "_FlushEvents" },
1654 		{ 0xA033, "_VInstall" },
1655 		{ 0xA034, "_VRemove" },
1656 		{ 0xA035, "_OffLine" },
1657 		{ 0xA036, "_MoreMasters" },
1658 		{ 0xA038, "_WriteParam" },
1659 		{ 0xA039, "_ReadDateTime" },
1660 		{ 0xA03A, "_SetDateTime" },
1661 		{ 0xA03B, "_Delay" },
1662 		{ 0xA03C, "_CmpString" },
1663 		{ 0xA03D, "_DrvrInstall" },
1664 		{ 0xA03E, "_DrvrRemove" },
1665 		{ 0xA03F, "_InitUtil" },
1666 		{ 0xA040, "_ResrvMem" },
1667 		{ 0xA041, "_SetFilLock" },
1668 		{ 0xA042, "_RstFilLock" },
1669 		{ 0xA043, "_SetFilType" },
1670 		{ 0xA044, "_SetFPos" },
1671 		{ 0xA045, "_FlushFile" },
1672 		{ 0xA047, "_SetTrapAddress" },
1673 		{ 0xA049, "_HPurge" },
1674 		{ 0xA04A, "_HNoPurge" },
1675 		{ 0xA04B, "_SetGrowZone" },
1676 		{ 0xA04C, "_CompactMem" },
1677 		{ 0xA04D, "_PurgeMem" },
1678 		{ 0xA04E, "_AddDrive" },
1679 		{ 0xA04F, "_RDrvrInstall" },
1680 		{ 0xA050, "_CompareString" },
1681 		{ 0xA051, "_ReadXPRam" },
1682 		{ 0xA052, "_WriteXPRam" },
1683 		{ 0xA054, "_UprString" },
1684 		{ 0xA055, "_StripAddress" },
1685 		{ 0xA056, "_LowerText" },
1686 		{ 0xA057, "_SetAppBase" },
1687 		{ 0xA058, "_InsTime" },
1688 		{ 0xA059, "_RmvTime" },
1689 		{ 0xA05A, "_PrimeTime" },
1690 		{ 0xA05B, "_PowerOff" },
1691 		{ 0xA05C, "_MemoryDispatch" },
1692 		{ 0xA05D, "_SwapMMUMode" },
1693 		{ 0xA05E, "_NMInstall" },
1694 		{ 0xA05F, "_NMRemove" },
1695 		{ 0xA060, "_FSDispatch" },
1696 		{ 0xA061, "_MaxBlock" },
1697 		{ 0xA063, "_MaxApplZone" },
1698 		{ 0xA064, "_MoveHHi" },
1699 		{ 0xA065, "_StackSpace" },
1700 		{ 0xA067, "_HSetRBit" },
1701 		{ 0xA068, "_HClrRBit" },
1702 		{ 0xA069, "_HGetState" },
1703 		{ 0xA06A, "_HSetState" },
1704 		{ 0xA06C, "_InitFS" },
1705 		{ 0xA06D, "_InitEvents" },
1706 		{ 0xA06E, "_SlotManager" },
1707 		{ 0xA06F, "_SlotVInstall" },
1708 		{ 0xA070, "_SlotVRemove" },
1709 		{ 0xA071, "_AttachVBL" },
1710 		{ 0xA072, "_DoVBLTask" },
1711 		{ 0xA075, "_SIntInstall" },
1712 		{ 0xA076, "_SIntRemove" },
1713 		{ 0xA077, "_CountADBs" },
1714 		{ 0xA078, "_GetIndADB" },
1715 		{ 0xA079, "_GetADBInfo" },
1716 		{ 0xA07A, "_SetADBInfo" },
1717 		{ 0xA07B, "_ADBReInit" },
1718 		{ 0xA07C, "_ADBOp" },
1719 		{ 0xA07D, "_GetDefaultStartup" },
1720 		{ 0xA07E, "_SetDefaultStartup" },
1721 		{ 0xA07F, "_InternalWait" },
1722 		{ 0xA080, "_GetVideoDefault" },
1723 		{ 0xA081, "_SetVideoDefault" },
1724 		{ 0xA082, "_`nstall" },
1725 		{ 0xA083, "_SetOSDefault" },
1726 		{ 0xA084, "_GetOSDefault" },
1727 		{ 0xA085, "_PMgrOp" },
1728 		{ 0xA086, "_IOPInfoAccess" },
1729 		{ 0xA087, "_IOPMsgRequest" },
1730 		{ 0xA088, "_IOPMoveData" },
1731 		{ 0xA089, "_SCSIAtomic" },
1732 		{ 0xA08A, "_Sleep" },
1733 		{ 0xA08B, "_CommToolboxDispatch" },
1734 		{ 0xA08D, "_DebugUtil" },
1735 		{ 0xA08F, "_DeferUserFn" },
1736 		{ 0xA090, "_SysEnvirons" },
1737 		{ 0xA092, "_EgretDispatch" },
1738 		{ 0xA094, "_ServerDispatch" },
1739 		{ 0xA09E, "_PowerMgrDispatch" },
1740 		{ 0xA09F, "_PowerDispatch" },
1741 		{ 0xA0A4, "_HeapDispatch" },
1742 		{ 0xA0AC, "_FSMDispatch" },
1743 		{ 0xA0AE, "_VADBProc" },
1744 		{ 0xA0DD, "_PPC" },
1745 		{ 0xA0FE, "_TEFindWord" },
1746 		{ 0xA0FF, "_TEFindLine" },
1747 		{ 0xA11A, "_GetZone" },
1748 		{ 0xA11D, "_MaxMem" },
1749 		{ 0xA11E, "_NewPtr" },
1750 		{ 0xA122, "_NewHandle" },
1751 		{ 0xA126, "_HandleZone" },
1752 		{ 0xA128, "_RecoverHandle" },
1753 		{ 0xA12F, "_PPostEvent" },
1754 		{ 0xA146, "_GetTrapAddress" },
1755 		{ 0xA148, "_PtrZone" },
1756 		{ 0xA162, "_PurgeSpace" },
1757 		{ 0xA166, "_NewEmptyHandle" },
1758 		{ 0xA193, "_Microseconds" },
1759 		{ 0xA198, "_HWPriv" },
1760 		{ 0xA1AD, "_Gestalt" },
1761 		{ 0xA200, "_HOpen" },
1762 		{ 0xA207, "_HGetVInfo" },
1763 		{ 0xA208, "_HCreate" },
1764 		{ 0xA209, "_HDelete" },
1765 		{ 0xA20A, "_HOpenRF" },
1766 		{ 0xA20B, "_HRename" },
1767 		{ 0xA20C, "_HGetFileInfo" },
1768 		{ 0xA20D, "_HSetFileInfo" },
1769 		{ 0xA20E, "_HUnmountVol" },
1770 		{ 0xA210, "_AllocContig" },
1771 		{ 0xA214, "_HGetVol" },
1772 		{ 0xA215, "_HSetVol" },
1773 		{ 0xA22E, "_BlockMoveData" },
1774 		{ 0xA241, "_HSetFLock" },
1775 		{ 0xA242, "_HRstFLock" },
1776 		{ 0xA247, "_SetOSTrapAddress" },
1777 		{ 0xA256, "_StripText" },
1778 		{ 0xA260, "_HFSDispatch" },
1779 		{ 0xA285, "_IdleUpdate" },
1780 		{ 0xA28A, "_SlpQInstall" },
1781 		{ 0xA31E, "_NewPtrClear" },
1782 		{ 0xA322, "_NewHandleClear" },
1783 		{ 0xA346, "_GetOSTrapAddress" },
1784 		{ 0xA3AD, "_NewGestalt" },
1785 		{ 0xA456, "_UpperText" },
1786 		{ 0xA458, "_InsXTime" },
1787 		{ 0xA485, "_IdleState" },
1788 		{ 0xA48A, "_SlpQRemove" },
1789 		{ 0xA51E, "_NewPtrSys" },
1790 		{ 0xA522, "_NewHandleSys" },
1791 		{ 0xA562, "_PurgeSpaceSys" },
1792 		{ 0xA5AD, "_ReplaceGestalt" },
1793 		{ 0xA647, "_SetToolBoxTrapAddress" },
1794 		{ 0xA656, "_StripUpperText" },
1795 		{ 0xA685, "_SerialPower" },
1796 		{ 0xA71E, "_NewPtrSysClear" },
1797 		{ 0xA722, "_NewHandleSysClear" },
1798 		{ 0xA746, "_GetToolBoxTrapAddress" },
1799 		{ 0xA7AD, "_GetGestaltProcPtr" },
1800 		{ 0xA800, "_SoundDispatch" },
1801 		{ 0xA801, "_SndDisposeChannel" },
1802 		{ 0xA802, "_SndAddModifier" },
1803 		{ 0xA803, "_SndDoCommand" },
1804 		{ 0xA804, "_SndDoImmediate" },
1805 		{ 0xA805, "_SndPlay" },
1806 		{ 0xA806, "_SndControl" },
1807 		{ 0xA807, "_SndNewChannel" },
1808 		{ 0xA808, "_InitProcMenu" },
1809 		{ 0xA809, "_GetControlVariant" },
1810 		{ 0xA80A, "_GetWVariant" },
1811 		{ 0xA80B, "_PopUpMenuSelect" },
1812 		{ 0xA80C, "_RGetResource" },
1813 		{ 0xA811, "_TESelView" },
1814 		{ 0xA812, "_TEPinScroll" },
1815 		{ 0xA813, "_TEAutoView" },
1816 		{ 0xA814, "_SetFractEnable" },
1817 		{ 0xA815, "_SCSIDispatch" },
1818 		{ 0xA817, "_CopyMask" },
1819 		{ 0xA819, "_XMunger" },
1820 		{ 0xA81A, "_HOpenResFile" },
1821 		{ 0xA81B, "_HCreateResFile" },
1822 		{ 0xA81D, "_InvalMenuBar" },
1823 		{ 0xA821, "_MaxSizeRsrc" },
1824 		{ 0xA822, "_ResourceDispatch" },
1825 		{ 0xA823, "_AliasDispatch" },
1826 		{ 0xA824, "_HFSUtilDispatch" },
1827 		{ 0xA825, "_MenuDispatch" },
1828 		{ 0xA826, "_InsertMenuItem" },
1829 		{ 0xA827, "_HideDialogItem" },
1830 		{ 0xA828, "_ShowDialogItem" },
1831 		{ 0xA82A, "_ComponentDispatch" },
1832 		{ 0xA833, "_ScrnBitMap" },
1833 		{ 0xA834, "_SetFScaleDisable" },
1834 		{ 0xA835, "_FontMetrics" },
1835 		{ 0xA836, "_GetMaskTable" },
1836 		{ 0xA837, "_MeasureText" },
1837 		{ 0xA838, "_CalcMask" },
1838 		{ 0xA839, "_SeedFill" },
1839 		{ 0xA83A, "_ZoomWindow" },
1840 		{ 0xA83B, "_TrackBox" },
1841 		{ 0xA83C, "_TEGetOffset" },
1842 		{ 0xA83D, "_TEDispatch" },
1843 		{ 0xA83E, "_TEStyleNew" },
1844 		{ 0xA847, "_FracCos" },
1845 		{ 0xA848, "_FracSin" },
1846 		{ 0xA849, "_FracSqrt" },
1847 		{ 0xA84A, "_FracMul" },
1848 		{ 0xA84B, "_FracDiv" },
1849 		{ 0xA84D, "_FixDiv" },
1850 		{ 0xA84E, "_GetItemCmd" },
1851 		{ 0xA84F, "_SetItemCmd" },
1852 		{ 0xA850, "_InitCursor" },
1853 		{ 0xA851, "_SetCursor" },
1854 		{ 0xA852, "_HideCursor" },
1855 		{ 0xA853, "_ShowCursor" },
1856 		{ 0xA854, "_FontDispatch" },
1857 		{ 0xA855, "_ShieldCursor" },
1858 		{ 0xA856, "_ObscureCursor" },
1859 		{ 0xA858, "_BitAnd" },
1860 		{ 0xA859, "_BitXOr" },
1861 		{ 0xA85A, "_BitNot" },
1862 		{ 0xA85B, "_BitOr" },
1863 		{ 0xA85C, "_BitShift" },
1864 		{ 0xA85D, "_BitTst" },
1865 		{ 0xA85E, "_BitSet" },
1866 		{ 0xA85F, "_BitClr" },
1867 		{ 0xA860, "_WaitNextEvent" },
1868 		{ 0xA861, "_Random" },
1869 		{ 0xA862, "_ForeColor" },
1870 		{ 0xA863, "_BackColor" },
1871 		{ 0xA864, "_ColorBit" },
1872 		{ 0xA865, "_GetPixel" },
1873 		{ 0xA866, "_StuffHex" },
1874 		{ 0xA867, "_LongMul" },
1875 		{ 0xA868, "_FixMul" },
1876 		{ 0xA869, "_FixRatio" },
1877 		{ 0xA86A, "_HiWord" },
1878 		{ 0xA86B, "_LoWord" },
1879 		{ 0xA86C, "_FixRound" },
1880 		{ 0xA86D, "_InitPort" },
1881 		{ 0xA86E, "_InitGraf" },
1882 		{ 0xA86F, "_OpenPort" },
1883 		{ 0xA870, "_LocalToGlobal" },
1884 		{ 0xA871, "_GlobalToLocal" },
1885 		{ 0xA872, "_GrafDevice" },
1886 		{ 0xA873, "_SetPort" },
1887 		{ 0xA874, "_GetPort" },
1888 		{ 0xA875, "_SetPBits" },
1889 		{ 0xA876, "_PortSize" },
1890 		{ 0xA877, "_MovePortTo" },
1891 		{ 0xA878, "_SetOrigin" },
1892 		{ 0xA879, "_SetClip" },
1893 		{ 0xA87A, "_GetClip" },
1894 		{ 0xA87B, "_ClipRect" },
1895 		{ 0xA87C, "_BackPat" },
1896 		{ 0xA87D, "_ClosePort" },
1897 		{ 0xA87E, "_AddPt" },
1898 		{ 0xA87F, "_SubPt" },
1899 		{ 0xA880, "_SetPt" },
1900 		{ 0xA881, "_EqualPt" },
1901 		{ 0xA882, "_StdText" },
1902 		{ 0xA883, "_DrawChar" },
1903 		{ 0xA884, "_DrawString" },
1904 		{ 0xA885, "_DrawText" },
1905 		{ 0xA886, "_TextWidth" },
1906 		{ 0xA887, "_TextFont" },
1907 		{ 0xA888, "_TextFace" },
1908 		{ 0xA889, "_TextMode" },
1909 		{ 0xA88A, "_TextSize" },
1910 		{ 0xA88B, "_GetFontInfo" },
1911 		{ 0xA88C, "_StringWidth" },
1912 		{ 0xA88D, "_CharWidth" },
1913 		{ 0xA88E, "_SpaceExtra" },
1914 		{ 0xA88F, "_OSDispatch" },
1915 		{ 0xA890, "_StdLine" },
1916 		{ 0xA891, "_LineTo" },
1917 		{ 0xA892, "_Line" },
1918 		{ 0xA893, "_MoveTo" },
1919 		{ 0xA894, "_Move" },
1920 		{ 0xA895, "_ShutDown" },
1921 		{ 0xA896, "_HidePen" },
1922 		{ 0xA897, "_ShowPen" },
1923 		{ 0xA898, "_GetPenState" },
1924 		{ 0xA899, "_SetPenState" },
1925 		{ 0xA89A, "_GetPen" },
1926 		{ 0xA89B, "_PenSize" },
1927 		{ 0xA89C, "_PenMode" },
1928 		{ 0xA89D, "_PenPat" },
1929 		{ 0xA89E, "_PenNormal" },
1930 		{ 0xA89F, "_Moof" },
1931 		{ 0xA8A0, "_StdRect" },
1932 		{ 0xA8A1, "_FrameRect" },
1933 		{ 0xA8A2, "_PaintRect" },
1934 		{ 0xA8A3, "_EraseRect" },
1935 		{ 0xA8A4, "_InverRect" },
1936 		{ 0xA8A5, "_FillRect" },
1937 		{ 0xA8A6, "_EqualRect" },
1938 		{ 0xA8A7, "_SetRect" },
1939 		{ 0xA8A8, "_OffsetRect" },
1940 		{ 0xA8A9, "_InsetRect" },
1941 		{ 0xA8AA, "_SectRect" },
1942 		{ 0xA8AB, "_UnionRect" },
1943 		{ 0xA8AD, "_PtInRect" },
1944 		{ 0xA8AE, "_EmptyRect" },
1945 		{ 0xA8AF, "_StdRRect" },
1946 		{ 0xA8B0, "_FrameRoundRect" },
1947 		{ 0xA8B1, "_PaintRoundRect" },
1948 		{ 0xA8B2, "_EraseRoundRect" },
1949 		{ 0xA8B3, "_InverRoundRect" },
1950 		{ 0xA8B4, "_FillRoundRect" },
1951 		{ 0xA8B5, "_ScriptUtil" },
1952 		{ 0xA8B6, "_StdOval" },
1953 		{ 0xA8B7, "_FrameOval" },
1954 		{ 0xA8B8, "_PaintOval" },
1955 		{ 0xA8B9, "_EraseOval" },
1956 		{ 0xA8BA, "_InvertOval" },
1957 		{ 0xA8BB, "_FillOval" },
1958 		{ 0xA8BC, "_SlopeFromAngle" },
1959 		{ 0xA8BD, "_StdArc" },
1960 		{ 0xA8BE, "_FrameArc" },
1961 		{ 0xA8BF, "_PaintArc" },
1962 		{ 0xA8C0, "_EraseArc" },
1963 		{ 0xA8C1, "_InvertArc" },
1964 		{ 0xA8C2, "_FillArc" },
1965 		{ 0xA8C3, "_PtToAngle" },
1966 		{ 0xA8C4, "_AngleFromSlope" },
1967 		{ 0xA8C5, "_StdPoly" },
1968 		{ 0xA8C6, "_FramePoly" },
1969 		{ 0xA8C7, "_PaintPoly" },
1970 		{ 0xA8C8, "_ErasePoly" },
1971 		{ 0xA8C9, "_InvertPoly" },
1972 		{ 0xA8CA, "_FillPoly" },
1973 		{ 0xA8CB, "_OpenPoly" },
1974 		{ 0xA8CC, "_ClosePoly" },
1975 		{ 0xA8CD, "_KillPoly" },
1976 		{ 0xA8CE, "_OffsetPoly" },
1977 		{ 0xA8CF, "_PackBits" },
1978 		{ 0xA8D0, "_UnpackBits" },
1979 		{ 0xA8D1, "_StdRgn" },
1980 		{ 0xA8D2, "_FrameRgn" },
1981 		{ 0xA8D3, "_PaintRgn" },
1982 		{ 0xA8D4, "_EraseRgn" },
1983 		{ 0xA8D5, "_InverRgn" },
1984 		{ 0xA8D6, "_FillRgn" },
1985 		{ 0xA8D7, "_BitMapToRegion" },
1986 		{ 0xA8D8, "_NewRgn" },
1987 		{ 0xA8D9, "_DisposeRgn" },
1988 		{ 0xA8DA, "_OpenRgn" },
1989 		{ 0xA8DB, "_CloseRgn" },
1990 		{ 0xA8DC, "_CopyRgn" },
1991 		{ 0xA8DD, "_SetEmptyRgn" },
1992 		{ 0xA8DE, "_SetRecRgn" },
1993 		{ 0xA8DF, "_RectRgn" },
1994 		{ 0xA8E0, "_OffsetRgn" },
1995 		{ 0xA8E1, "_InsetRgn" },
1996 		{ 0xA8E2, "_EmptyRgn" },
1997 		{ 0xA8E3, "_EqualRgn" },
1998 		{ 0xA8E4, "_SectRgn" },
1999 		{ 0xA8E5, "_UnionRgn" },
2000 		{ 0xA8E6, "_DiffRgn" },
2001 		{ 0xA8E7, "_XOrRgn" },
2002 		{ 0xA8E8, "_PtInRgn" },
2003 		{ 0xA8E9, "_RectInRgn" },
2004 		{ 0xA8EA, "_SetStdProcs" },
2005 		{ 0xA8EB, "_StdBits" },
2006 		{ 0xA8EC, "_CopyBits" },
2007 		{ 0xA8ED, "_StdTxMeas" },
2008 		{ 0xA8EE, "_StdGetPic" },
2009 		{ 0xA8EF, "_ScrollRect" },
2010 		{ 0xA8F0, "_StdPutPic" },
2011 		{ 0xA8F1, "_StdComment" },
2012 		{ 0xA8F2, "_PicComment" },
2013 		{ 0xA8F3, "_OpenPicture" },
2014 		{ 0xA8F4, "_ClosePicture" },
2015 		{ 0xA8F5, "_KillPicture" },
2016 		{ 0xA8F6, "_DrawPicture" },
2017 		{ 0xA8F7, "_Layout" },
2018 		{ 0xA8F8, "_ScalePt" },
2019 		{ 0xA8F9, "_MapPt" },
2020 		{ 0xA8FA, "_MapRect" },
2021 		{ 0xA8FB, "_MapRgn" },
2022 		{ 0xA8FC, "_MapPoly" },
2023 		{ 0xA8FD, "_PrGlue" },
2024 		{ 0xA8FE, "_InitFonts" },
2025 		{ 0xA8FF, "_GetFName" },
2026 		{ 0xA900, "_GetFNum" },
2027 		{ 0xA901, "_FMSwapFont" },
2028 		{ 0xA902, "_RealFont" },
2029 		{ 0xA903, "_SetFontLock" },
2030 		{ 0xA904, "_DrawGrowIcon" },
2031 		{ 0xA905, "_DragGrayRgn" },
2032 		{ 0xA906, "_NewString" },
2033 		{ 0xA907, "_SetString" },
2034 		{ 0xA908, "_ShowHide" },
2035 		{ 0xA909, "_CalcVis" },
2036 		{ 0xA90A, "_CalcVBehind" },
2037 		{ 0xA90B, "_ClipAbove" },
2038 		{ 0xA90C, "_PaintOne" },
2039 		{ 0xA90D, "_PaintBehind" },
2040 		{ 0xA90E, "_SaveOld" },
2041 		{ 0xA90F, "_DrawNew" },
2042 		{ 0xA910, "_GetWMgrPort" },
2043 		{ 0xA911, "_CheckUpDate" },
2044 		{ 0xA912, "_InitWindows" },
2045 		{ 0xA913, "_NewWindow" },
2046 		{ 0xA914, "_DisposeWindow" },
2047 		{ 0xA915, "_ShowWindow" },
2048 		{ 0xA916, "_HideWindow" },
2049 		{ 0xA917, "_GetWRefCon" },
2050 		{ 0xA918, "_SetWRefCon" },
2051 		{ 0xA919, "_GetWTitle" },
2052 		{ 0xA91A, "_SetWTitle" },
2053 		{ 0xA91B, "_MoveWindow" },
2054 		{ 0xA91C, "_HiliteWindow" },
2055 		{ 0xA91D, "_SizeWindow" },
2056 		{ 0xA91E, "_TrackGoAway" },
2057 		{ 0xA91F, "_SelectWindow" },
2058 		{ 0xA920, "_BringToFront" },
2059 		{ 0xA921, "_SendBehind" },
2060 		{ 0xA922, "_BeginUpDate" },
2061 		{ 0xA923, "_EndUpDate" },
2062 		{ 0xA924, "_FrontWindow" },
2063 		{ 0xA925, "_DragWindow" },
2064 		{ 0xA926, "_DragTheRgn" },
2065 		{ 0xA927, "_InvalRgn" },
2066 		{ 0xA928, "_InvalRect" },
2067 		{ 0xA929, "_ValidRgn" },
2068 		{ 0xA92A, "_ValidRect" },
2069 		{ 0xA92B, "_GrowWindow" },
2070 		{ 0xA92C, "_FindWindow" },
2071 		{ 0xA92D, "_CloseWindow" },
2072 		{ 0xA92E, "_SetWindowPic" },
2073 		{ 0xA92F, "_GetWindowPic" },
2074 		{ 0xA930, "_InitMenus" },
2075 		{ 0xA931, "_NewMenu" },
2076 		{ 0xA932, "_DisposeMenu" },
2077 		{ 0xA933, "_AppendMenu" },
2078 		{ 0xA934, "_ClearMenuBar" },
2079 		{ 0xA935, "_InsertMenu" },
2080 		{ 0xA936, "_DeleteMenu" },
2081 		{ 0xA937, "_DrawMenuBar" },
2082 		{ 0xA938, "_HiliteMenu" },
2083 		{ 0xA939, "_EnableItem" },
2084 		{ 0xA93A, "_DisableItem" },
2085 		{ 0xA93B, "_GetMenuBar" },
2086 		{ 0xA93C, "_SetMenuBar" },
2087 		{ 0xA93D, "_MenuSelect" },
2088 		{ 0xA93E, "_MenuKey" },
2089 		{ 0xA93F, "_GetItmIcon" },
2090 		{ 0xA940, "_SetItmIcon" },
2091 		{ 0xA941, "_GetItmStyle" },
2092 		{ 0xA942, "_SetItmStyle" },
2093 		{ 0xA943, "_GetItmMark" },
2094 		{ 0xA944, "_SetItmMark" },
2095 		{ 0xA945, "_CheckItem" },
2096 		{ 0xA946, "_GetMenuItemText" },
2097 		{ 0xA947, "_SetMenuItemText" },
2098 		{ 0xA948, "_CalcMenuSize" },
2099 		{ 0xA949, "_GetMenuHandle" },
2100 		{ 0xA94A, "_SetMFlash" },
2101 		{ 0xA94B, "_PlotIcon" },
2102 		{ 0xA94C, "_FlashMenuBar" },
2103 		{ 0xA94D, "_AppendResMenu" },
2104 		{ 0xA94E, "_PinRect" },
2105 		{ 0xA94F, "_DeltaPoint" },
2106 		{ 0xA950, "_CountMItems" },
2107 		{ 0xA951, "_InsertResMenu" },
2108 		{ 0xA952, "_DeleteMenuItem" },
2109 		{ 0xA953, "_UpdtControl" },
2110 		{ 0xA954, "_NewControl" },
2111 		{ 0xA955, "_DisposeControl" },
2112 		{ 0xA956, "_KillControls" },
2113 		{ 0xA957, "_ShowControl" },
2114 		{ 0xA958, "_HideControl" },
2115 		{ 0xA959, "_MoveControl" },
2116 		{ 0xA95A, "_GetControlReference" },
2117 		{ 0xA95B, "_SetControlReference" },
2118 		{ 0xA95C, "_SizeControl" },
2119 		{ 0xA95D, "_HiliteControl" },
2120 		{ 0xA95E, "_GetControlTitle" },
2121 		{ 0xA95F, "_SetControlTitle" },
2122 		{ 0xA960, "_GetControlValue" },
2123 		{ 0xA961, "_GetControlMinimum" },
2124 		{ 0xA962, "_GetControlMaximum" },
2125 		{ 0xA963, "_SetControlValue" },
2126 		{ 0xA964, "_SetControlMinimum" },
2127 		{ 0xA965, "_SetControlMaximum" },
2128 		{ 0xA966, "_TestControl" },
2129 		{ 0xA967, "_DragControl" },
2130 		{ 0xA968, "_TrackControl" },
2131 		{ 0xA969, "_DrawControls" },
2132 		{ 0xA96A, "_GetControlAction" },
2133 		{ 0xA96B, "_SetControlAction" },
2134 		{ 0xA96C, "_FindControl" },
2135 		{ 0xA96E, "_Dequeue" },
2136 		{ 0xA96F, "_Enqueue" },
2137 		{ 0xA970, "_GetNextEvent" },
2138 		{ 0xA971, "_EventAvail" },
2139 		{ 0xA972, "_GetMouse" },
2140 		{ 0xA973, "_StillDown" },
2141 		{ 0xA974, "_Button" },
2142 		{ 0xA975, "_TickCount" },
2143 		{ 0xA976, "_GetKeys" },
2144 		{ 0xA977, "_WaitMouseUp" },
2145 		{ 0xA978, "_UpdtDialog" },
2146 		{ 0xA97B, "_InitDialogs" },
2147 		{ 0xA97C, "_GetNewDialog" },
2148 		{ 0xA97D, "_NewDialog" },
2149 		{ 0xA97E, "_SelectDialogItemText" },
2150 		{ 0xA97F, "_IsDialogEvent" },
2151 		{ 0xA980, "_DialogSelect" },
2152 		{ 0xA981, "_DrawDialog" },
2153 		{ 0xA982, "_CloseDialog" },
2154 		{ 0xA983, "_DisposeDialog" },
2155 		{ 0xA984, "_FindDialogItem" },
2156 		{ 0xA985, "_Alert" },
2157 		{ 0xA986, "_StopAlert" },
2158 		{ 0xA987, "_NoteAlert" },
2159 		{ 0xA988, "_CautionAlert" },
2160 		{ 0xA98B, "_ParamText" },
2161 		{ 0xA98C, "_ErrorSound" },
2162 		{ 0xA98D, "_GetDialogItem" },
2163 		{ 0xA98E, "_SetDialogItem" },
2164 		{ 0xA98F, "_SetDialogItemText" },
2165 		{ 0xA990, "_GetDialogItemText" },
2166 		{ 0xA991, "_ModalDialog" },
2167 		{ 0xA992, "_DetachResource" },
2168 		{ 0xA993, "_SetResPurge" },
2169 		{ 0xA994, "_CurResFile" },
2170 		{ 0xA995, "_InitResources" },
2171 		{ 0xA996, "_RsrcZoneInit" },
2172 		{ 0xA997, "_OpenResFile" },
2173 		{ 0xA998, "_UseResFile" },
2174 		{ 0xA999, "_UpdateResFile" },
2175 		{ 0xA99A, "_CloseResFile" },
2176 		{ 0xA99B, "_SetResLoad" },
2177 		{ 0xA99C, "_CountResources" },
2178 		{ 0xA99D, "_GetIndResource" },
2179 		{ 0xA99E, "_CountTypes" },
2180 		{ 0xA99F, "_GetIndType" },
2181 		{ 0xA9A0, "_GetResource" },
2182 		{ 0xA9A1, "_GetNamedResource" },
2183 		{ 0xA9A2, "_LoadResource" },
2184 		{ 0xA9A3, "_ReleaseResource" },
2185 		{ 0xA9A4, "_HomeResFile" },
2186 		{ 0xA9A5, "_SizeRsrc" },
2187 		{ 0xA9A6, "_GetResAttrs" },
2188 		{ 0xA9A7, "_SetResAttrs" },
2189 		{ 0xA9A8, "_GetResInfo" },
2190 		{ 0xA9A9, "_SetResInfo" },
2191 		{ 0xA9AA, "_ChangedResource" },
2192 		{ 0xA9AB, "_AddResource" },
2193 		{ 0xA9AC, "_AddReference" },
2194 		{ 0xA9AD, "_RmveResource" },
2195 		{ 0xA9AE, "_RmveReference" },
2196 		{ 0xA9AF, "_ResError" },
2197 		{ 0xA9B0, "_WriteResource" },
2198 		{ 0xA9B1, "_CreateResFile" },
2199 		{ 0xA9B2, "_SystemEvent" },
2200 		{ 0xA9B3, "_SystemClick" },
2201 		{ 0xA9B4, "_SystemTask" },
2202 		{ 0xA9B5, "_SystemMenu" },
2203 		{ 0xA9B6, "_OpenDeskAcc" },
2204 		{ 0xA9B7, "_CloseDeskAcc" },
2205 		{ 0xA9B8, "_GetPattern" },
2206 		{ 0xA9B9, "_GetCursor" },
2207 		{ 0xA9BA, "_GetString" },
2208 		{ 0xA9BB, "_GetIcon" },
2209 		{ 0xA9BC, "_GetPicture" },
2210 		{ 0xA9BD, "_GetNewWindow" },
2211 		{ 0xA9BE, "_GetNewControl" },
2212 		{ 0xA9BF, "_GetRMenu" },
2213 		{ 0xA9C0, "_GetNewMBar" },
2214 		{ 0xA9C1, "_UniqueID" },
2215 		{ 0xA9C2, "_SysEdit" },
2216 		{ 0xA9C3, "_KeyTranslate" },
2217 		{ 0xA9C4, "_OpenRFPerm" },
2218 		{ 0xA9C5, "_RsrcMapEntry" },
2219 		{ 0xA9C6, "_SecondsToDate" },
2220 		{ 0xA9C7, "_DateToSeconds" },
2221 		{ 0xA9C8, "_SysBeep" },
2222 		{ 0xA9C9, "_SysError" },
2223 		{ 0xA9CA, "_PutIcon" },
2224 		{ 0xA9CB, "_TEGetText" },
2225 		{ 0xA9CC, "_TEInit" },
2226 		{ 0xA9CD, "_TEDispose" },
2227 		{ 0xA9CE, "_TETextBox" },
2228 		{ 0xA9CF, "_TESetText" },
2229 		{ 0xA9D0, "_TECalText" },
2230 		{ 0xA9D1, "_TESetSelect" },
2231 		{ 0xA9D2, "_TENew" },
2232 		{ 0xA9D3, "_TEUpdate" },
2233 		{ 0xA9D4, "_TEClick" },
2234 		{ 0xA9D5, "_TECopy" },
2235 		{ 0xA9D6, "_TECut" },
2236 		{ 0xA9D7, "_TEDelete" },
2237 		{ 0xA9D8, "_TEActivate" },
2238 		{ 0xA9D9, "_TEDeactivate" },
2239 		{ 0xA9DA, "_TEIdle" },
2240 		{ 0xA9DB, "_TEPaste" },
2241 		{ 0xA9DC, "_TEKey" },
2242 		{ 0xA9DD, "_TEScroll" },
2243 		{ 0xA9DE, "_TEInsert" },
2244 		{ 0xA9DF, "_TESetAlignment" },
2245 		{ 0xA9E0, "_Munger" },
2246 		{ 0xA9E1, "_HandToHand" },
2247 		{ 0xA9E2, "_PtrToXHand" },
2248 		{ 0xA9E3, "_PtrToHand" },
2249 		{ 0xA9E4, "_HandAndHand" },
2250 		{ 0xA9E5, "_InitPack" },
2251 		{ 0xA9E6, "_InitAllPacks" },
2252 		{ 0xA9EF, "_PtrAndHand" },
2253 		{ 0xA9F0, "_LoadSeg" },
2254 		{ 0xA9F1, "_UnLoadSeg" },
2255 		{ 0xA9F2, "_Launch" },
2256 		{ 0xA9F3, "_Chain" },
2257 		{ 0xA9F4, "_ExitToShell" },
2258 		{ 0xA9F5, "_GetAppParms" },
2259 		{ 0xA9F6, "_GetResFileAttrs" },
2260 		{ 0xA9F7, "_SetResFileAttrs" },
2261 		{ 0xA9F8, "_MethodDispatch" },
2262 		{ 0xA9F9, "_InfoScrap" },
2263 		{ 0xA9FA, "_UnloadScrap" },
2264 		{ 0xA9FB, "_LoadScrap" },
2265 		{ 0xA9FC, "_ZeroScrap" },
2266 		{ 0xA9FD, "_GetScrap" },
2267 		{ 0xA9FE, "_PutScrap" },
2268 		{ 0xA9FF, "_Debugger" },
2269 		{ 0xAA00, "_OpenCPort" },
2270 		{ 0xAA01, "_InitCPort" },
2271 		{ 0xAA02, "_CloseCPort" },
2272 		{ 0xAA03, "_NewPixMap" },
2273 		{ 0xAA04, "_DisposePixMap" },
2274 		{ 0xAA05, "_CopyPixMap" },
2275 		{ 0xAA06, "_SetPortPix" },
2276 		{ 0xAA07, "_NewPixPat" },
2277 		{ 0xAA08, "_DisposePixPat" },
2278 		{ 0xAA09, "_CopyPixPat" },
2279 		{ 0xAA0A, "_PenPixPat" },
2280 		{ 0xAA0B, "_BackPixPat" },
2281 		{ 0xAA0C, "_GetPixPat" },
2282 		{ 0xAA0D, "_MakeRGBPat" },
2283 		{ 0xAA0E, "_FillCRect" },
2284 		{ 0xAA0F, "_FillCOval" },
2285 		{ 0xAA10, "_FillCRoundRect" },
2286 		{ 0xAA11, "_FillCArc" },
2287 		{ 0xAA12, "_FillCRgn" },
2288 		{ 0xAA13, "_FillCPoly" },
2289 		{ 0xAA14, "_RGBForeColor" },
2290 		{ 0xAA15, "_RGBBackColor" },
2291 		{ 0xAA16, "_SetCPixel" },
2292 		{ 0xAA17, "_GetCPixel" },
2293 		{ 0xAA18, "_GetCTable" },
2294 		{ 0xAA19, "_GetForeColor" },
2295 		{ 0xAA1A, "_GetBackColor" },
2296 		{ 0xAA1B, "_GetCCursor" },
2297 		{ 0xAA1C, "_SetCCursor" },
2298 		{ 0xAA1D, "_AllocCursor" },
2299 		{ 0xAA1E, "_GetCIcon" },
2300 		{ 0xAA1F, "_PlotCIcon" },
2301 		{ 0xAA20, "_OpenCPicture" },
2302 		{ 0xAA21, "_OpColor" },
2303 		{ 0xAA22, "_HiliteColor" },
2304 		{ 0xAA23, "_CharExtra" },
2305 		{ 0xAA24, "_DisposeCTable" },
2306 		{ 0xAA25, "_DisposeCIcon" },
2307 		{ 0xAA26, "_DisposeCCursor" },
2308 		{ 0xAA27, "_GetMaxDevice" },
2309 		{ 0xAA28, "_GetCTSeed" },
2310 		{ 0xAA29, "_GetDeviceList" },
2311 		{ 0xAA2A, "_GetMainDevice" },
2312 		{ 0xAA2B, "_GetNextDevice" },
2313 		{ 0xAA2C, "_TestDeviceAttribute" },
2314 		{ 0xAA2D, "_SetDeviceAttribute" },
2315 		{ 0xAA2E, "_InitGDevice" },
2316 		{ 0xAA2F, "_NewGDevice" },
2317 		{ 0xAA30, "_DisposeGDevice" },
2318 		{ 0xAA31, "_SetGDevice" },
2319 		{ 0xAA32, "_GetGDevice" },
2320 		{ 0xAA35, "_InvertColor" },
2321 		{ 0xAA36, "_RealColor" },
2322 		{ 0xAA37, "_GetSubTable" },
2323 		{ 0xAA38, "_UpdatePixMap" },
2324 		{ 0xAA39, "_MakeITable" },
2325 		{ 0xAA3A, "_AddSearch" },
2326 		{ 0xAA3B, "_AddComp" },
2327 		{ 0xAA3C, "_SetClientID" },
2328 		{ 0xAA3D, "_ProtectEntry" },
2329 		{ 0xAA3E, "_ReserveEntry" },
2330 		{ 0xAA3F, "_SetEntries" },
2331 		{ 0xAA40, "_QDError" },
2332 		{ 0xAA41, "_SetWinColor" },
2333 		{ 0xAA42, "_GetAuxWin" },
2334 		{ 0xAA43, "_SetControlColor" },
2335 		{ 0xAA44, "_GetAuxiliaryControlRecord" },
2336 		{ 0xAA45, "_NewCWindow" },
2337 		{ 0xAA46, "_GetNewCWindow" },
2338 		{ 0xAA47, "_SetDeskCPat" },
2339 		{ 0xAA48, "_GetCWMgrPort" },
2340 		{ 0xAA49, "_SaveEntries" },
2341 		{ 0xAA4A, "_RestoreEntries" },
2342 		{ 0xAA4B, "_NewColorDialog" },
2343 		{ 0xAA4C, "_DelSearch" },
2344 		{ 0xAA4D, "_DelComp" },
2345 		{ 0xAA4E, "_SetStdCProcs" },
2346 		{ 0xAA4F, "_CalcCMask" },
2347 		{ 0xAA50, "_SeedCFill" },
2348 		{ 0xAA51, "_CopyDeepMask" },
2349 		{ 0xAA52, "_HFSPinaforeDispatch" },
2350 		{ 0xAA53, "_DictionaryDispatch" },
2351 		{ 0xAA54, "_TextServicesDispatch" },
2352 		{ 0xAA56, "_SpeechRecognitionDispatch" },
2353 		{ 0xAA57, "_DockingDispatch" },
2354 		{ 0xAA59, "_MixedModeDispatch" },
2355 		{ 0xAA5A, "_CodeFragmentDispatch" },
2356 		{ 0xAA5C, "_OCEUtils" },
2357 		{ 0xAA5D, "_DigitalSignature" },
2358 		{ 0xAA5E, "_TBDispatch" },
2359 		{ 0xAA60, "_DeleteMCEntries" },
2360 		{ 0xAA61, "_GetMCInfo" },
2361 		{ 0xAA62, "_SetMCInfo" },
2362 		{ 0xAA63, "_DisposeMCInfo" },
2363 		{ 0xAA64, "_GetMCEntry" },
2364 		{ 0xAA65, "_SetMCEntries" },
2365 		{ 0xAA66, "_MenuChoice" },
2366 		{ 0xAA67, "_ModalDialogMenuSetup" },
2367 		{ 0xAA68, "_DialogDispatch" },
2368 		{ 0xAA73, "_ControlDispatch" },
2369 		{ 0xAA74, "_AppearanceDispatch" },
2370 		{ 0xAA7E, "_SysDebugDispatch" },
2371 		{ 0xAA80, "_AVLTreeDispatch" },
2372 		{ 0xAA81, "_FileMappingDispatch" },
2373 		{ 0xAA90, "_InitPalettes" },
2374 		{ 0xAA91, "_NewPalette" },
2375 		{ 0xAA92, "_GetNewPalette" },
2376 		{ 0xAA93, "_DisposePalette" },
2377 		{ 0xAA94, "_ActivatePalette" },
2378 		{ 0xAA95, "_NSetPalette" },
2379 		{ 0xAA96, "_GetPalette" },
2380 		{ 0xAA97, "_PmForeColor" },
2381 		{ 0xAA98, "_PmBackColor" },
2382 		{ 0xAA99, "_AnimateEntry" },
2383 		{ 0xAA9A, "_AnimatePalette" },
2384 		{ 0xAA9B, "_GetEntryColor" },
2385 		{ 0xAA9C, "_SetEntryColor" },
2386 		{ 0xAA9D, "_GetEntryUsage" },
2387 		{ 0xAA9E, "_SetEntryUsage" },
2388 		{ 0xAAA1, "_CopyPalette" },
2389 		{ 0xAAA2, "_PaletteDispatch" },
2390 		{ 0xAAA3, "_CodecDispatch" },
2391 		{ 0xAAA4, "_ALMDispatch" },
2392 		{ 0xAADB, "_CursorDeviceDispatch" },
2393 		{ 0xAAF2, "_ControlStripDispatch" },
2394 		{ 0xAAF3, "_ExpansionManager" },
2395 		{ 0xAB1D, "_QDExtensions" },
2396 		{ 0xABC3, "_NQDMisc" },
2397 		{ 0xABC9, "_IconDispatch" },
2398 		{ 0xABCA, "_DeviceLoop" },
2399 		{ 0xABEB, "_DisplayDispatch" },
2400 		{ 0xABED, "_DragDispatch" },
2401 		{ 0xABF1, "_GestaltValueDispatch" },
2402 		{ 0xABF2, "_ThreadDispatch" },
2403 		{ 0xABF6, "_CollectionMgr" },
2404 		{ 0xABF8, "_StdOpcodeProc" },
2405 		{ 0xABFC, "_TranslationDispatch" },
2406 		{ 0xABFF, "_DebugStr" }
2407 	};
2408 
2409 	int i;
2410 
2411 	for (i = 0; i < ARRAY_LENGTH(traps); i++)
2412 	{
2413 		if (traps[i].trap == opcode)
2414 			return traps[i].name;
2415 	}
2416 	return nullptr;
2417 }
2418 
2419 
2420 
mac_dasm_override(std::ostream & stream,offs_t pc,const util::disasm_interface::data_buffer & opcodes,const util::disasm_interface::data_buffer & params)2421 offs_t mac_state::mac_dasm_override(std::ostream &stream, offs_t pc, const util::disasm_interface::data_buffer &opcodes, const util::disasm_interface::data_buffer &params)
2422 {
2423 	uint16_t opcode;
2424 	unsigned result = 0;
2425 	const char *trap;
2426 
2427 	opcode = opcodes.r16(pc);
2428 	if ((opcode & 0xF000) == 0xA000)
2429 	{
2430 		trap = lookup_trap(opcode);
2431 		if (trap != nullptr)
2432 		{
2433 			stream << trap;
2434 			result = 2 | util::disasm_interface::SUPPORTED;
2435 		}
2436 	}
2437 	return result;
2438 }
2439 
2440 
2441 
2442 #ifdef MAC_TRACETRAP
mac_tracetrap(const char * cpu_name_local,int addr,int trap)2443 void mac_state::mac_tracetrap(const char *cpu_name_local, int addr, int trap)
2444 {
2445 	struct sonycscodeentry
2446 	{
2447 		int csCode;
2448 		const char *name;
2449 	};
2450 
2451 	static const sonycscodeentry cscodes[] =
2452 	{
2453 		{ 1, "KillIO" },
2454 		{ 5, "VerifyDisk" },
2455 		{ 6, "FormatDisk" },
2456 		{ 7, "EjectDisk" },
2457 		{ 8, "SetTagBuffer" },
2458 		{ 9, "TrackCacheControl" },
2459 		{ 23, "ReturnDriveInfo" }
2460 	};
2461 
2462 	static const char *const scsisels[] =
2463 	{
2464 		"SCSIReset",    /* $00 */
2465 		"SCSIGet",      /* $01 */
2466 		"SCSISelect",   /* $02 */
2467 		"SCSICmd",      /* $03 */
2468 		"SCSIComplete", /* $04 */
2469 		"SCSIRead",     /* $05 */
2470 		"SCSIWrite",    /* $06 */
2471 		nullptr,           /* $07 */
2472 		"SCSIRBlind",   /* $08 */
2473 		"SCSIWBlind",   /* $09 */
2474 		"SCSIStat",     /* $0A */
2475 		"SCSISelAtn",   /* $0B */
2476 		"SCSIMsgIn",    /* $0C */
2477 		"SCSIMsgOut",   /* $0D */
2478 	};
2479 
2480 	int i, a0, a7, d0, d1;
2481 	int csCode, ioVRefNum, ioRefNum, ioCRefNum, ioCompletion, ioBuffer, ioReqCount, ioPosOffset;
2482 	char *s;
2483 	unsigned char *mem;
2484 	char buf[256];
2485 	const char *trapstr;
2486 
2487 	trapstr = lookup_trap(trap);
2488 	if (trapstr)
2489 		strcpy(buf, trapstr);
2490 	else
2491 		sprintf(buf, "Trap $%04x", trap);
2492 
2493 	s = &buf[strlen(buf)];
2494 	mem = mac_ram_ptr;
2495 	a0 = M68K_A0);
2496 	a7 = cpu_get_reg(M68K_A7);
2497 	d0 = cpu_get_reg(M68K_D0);
2498 	d1 = cpu_get_reg(M68K_D1);
2499 
2500 	switch(trap)
2501 	{
2502 	case 0xa004:    /* _Control */
2503 		ioVRefNum = *((int16_t*) (mem + a0 + 22));
2504 		ioCRefNum = *((int16_t*) (mem + a0 + 24));
2505 		csCode = *((uint16_t*) (mem + a0 + 26));
2506 		sprintf(s->state().state_int(" ioVRefNum=%i ioCRefNum=%i csCode=%i", ioVRefNum, ioCRefNum, csCode);
2507 
2508 		for (i = 0; i < ARRAY_LENGTH(cscodes); i++)
2509 		{
2510 			if (cscodes[i].csCode == csCode)
2511 			{
2512 				strcat(s, "=");
2513 				strcat(s, cscodes[i].name);
2514 				break;
2515 			}
2516 		}
2517 		break;
2518 
2519 	case 0xa002:    /* _Read */
2520 		ioCompletion = (*((int16_t*) (mem + a0 + 12)) << 16) + *((int16_t*) (mem + a0 + 14));
2521 		ioVRefNum = *((int16_t*) (mem + a0 + 22));
2522 		ioRefNum = *((int16_t*) (mem + a0 + 24));
2523 		ioBuffer = (*((int16_t*) (mem + a0 + 32)) << 16) + *((int16_t*) (mem + a0 + 34));
2524 		ioReqCount = (*((int16_t*) (mem + a0 + 36)) << 16) + *((int16_t*) (mem + a0 + 38));
2525 		ioPosOffset = (*((int16_t*) (mem + a0 + 46)) << 16) + *((int16_t*) (mem + a0 + 48));
2526 		sprintf(s, " ioCompletion=0x%08x ioVRefNum=%i ioRefNum=%i ioBuffer=0x%08x ioReqCount=%i ioPosOffset=%i",
2527 			ioCompletion, ioVRefNum, ioRefNum, ioBuffer, ioReqCount, ioPosOffset);
2528 		break;
2529 
2530 	case 0xa04e:    /* _AddDrive */
2531 		sprintf(s, " drvrRefNum=%i drvNum=%i qEl=0x%08x", (int) (int16_t) d0, (int) (int16_t) d1, a0);
2532 		break;
2533 
2534 	case 0xa9a0:    /* _GetResource */
2535 		/* HACKHACK - the 'type' output assumes that the host is little endian
2536 		 * since this is just trace code it isn't much of an issue
2537 		 */
2538 		sprintf(s, " type='%c%c%c%c' id=%i", (char) mem[a7+3], (char) mem[a7+2],
2539 			(char) mem[a7+5], (char) mem[a7+4], *((int16_t*) (mem + a7)));
2540 		break;
2541 
2542 	case 0xa815:    /* _SCSIDispatch */
2543 		i = *((uint16_t*) (mem + a7));
2544 		if (i < ARRAY_LENGTH(scsisels))
2545 			if (scsisels[i])
2546 				sprintf(s, " (%s)", scsisels[i]);
2547 		break;
2548 	}
2549 
2550 	logerror("mac_trace_trap: %s at 0x%08x: %s\n",cpu_name_local, addr, buf);
2551 }
2552 #endif
2553