1 // license:BSD-3-Clause
2 // copyright-holders:Miodrag Milanovic, R. Belmont
3 /***************************************************************************
4
5 Sun-2 Models
6 ------------
7
8 2/120
9 Processor(s): 68010 @ 10MHz
10 CPU: 501-1007/1051
11 Chassis type: deskside
12 Bus: Multibus (9 slots)
13 Oscillator(s): 39.3216MHz
14 Memory: 7M physical
15 Notes: First machines in deskside chassis. Serial
16 microswitch keyboard (type 2), Mouse Systems
17 optical mouse (Sun-2).
18
19 2/100U
20 Processor(s): 68010 @ 10MHz
21 CPU: 501-1007
22 Bus: Multibus
23 Notes: Upgraded Sun 100. Replaced CPU and memory boards
24 with first-generation Sun-2 CPU and memory
25 boards so original customers could run SunOS
26 1.x. Still has parallel kb/mouse interface so
27 type 1 keyboards and Sun-1 mice could be
28 connected.
29
30 2/150U
31 Notes: Apparently also an upgraded Sun-1.
32
33 2/170
34 Chassis type: rackmount
35 Bus: Multibus (15 slots)
36 Notes: Rackmount version of 2/120, with more slots.
37
38 2/50
39 Processor(s): 68010 @ 10MHz
40 CPU: 501-1141/1142/1143/1426/1427/1428
41 Chassis type: wide pizza box
42 Bus: VME (2 slots)
43 Oscillator(s): 19.6608MHz, 16MHz (Ethernet/VMEbus), 100MHz
44 (video), 24MHz ("for special applications")
45 Memory: 7M physical
46 Notes: The (type 2) keyboard and mouse attach via an
47 adapter that accepts two modular plugs and
48 attaches to a DB15 port; later on, units were
49 apparently shipped with type 3 keyboards. The
50 CPU boards have a double-width back panel but
51 are otherwise identical to those in the 2/130
52 and 2/160.
53
54 2/130
55 2/160
56 Processor(s): 68010 @ 10MHz
57 CPU: 501-1144/1145/1146/1429/1430/1431
58 Chassis type: deskside
59 Bus: VME (12 slots)
60 Memory: 7M physical
61 Notes: First machine in 12-slot deskside VME chassis.
62 Has four-fan cooling tray instead of six as in
63 later machines, which led to cooling problems
64 with lots of cards. Backplane has only four P2
65 memory connectors bussed instead of six as in
66 later 12-slot backplanes; SCSI passthrough is in
67 slot 6 instead of 7 as in later 12-slot
68 backplanes. Upgradeable to a 3/160 by replacing
69 the CPU board. No information on the differences
70 between the 2/130 and the 2/160.
71
72
73 25/08/2009 Skeleton driver.
74 31/05/2016 Main screen turn on.
75
76 How the architecture works:
77 - There are 3 address sub-spaces: CPU layer, MMU layer, and device layer
78 - CPU layer uses MOVS instructions to output FC 3.
79 - CPU layer: the low-order address bits A4-A1 specify the device
80 0100x = ID Prom
81 0101x = Diagnostic register (8 bits, 8 LEDs, bit = 0 for ON, 1 for OFF)
82 0110x = Bus error register
83 0111x = System enable register
84
85 Bits A5+ address the actual individual parts of these things. ID Prom bytes
86 are at 0x0008, 0x0808, 0x1008, 0x1808, 0x2008, 0x2808, 0x3008, etc.
87
88 System enable bits:
89 b0 = enable parity generation
90 b1 = cause level 1 IRQ
91 b2 = cause level 2 IRQ
92 b3 = cause level 3 IRQ
93 b4 = enable parity error checking
94 b5 = enable DVMA
95 b6 = enable all interrupts
96 b7 = boot state (0 = boot, 1 = normal)
97 In boot state, all supervisor program reads go to the EPROM.
98
99 - MMU layer: also accessed via FC 3
100 PAGE MAP at 0 + V
101 SEGMENT MAP at 4 + V
102 CONTEXT REG at 6 + V
103
104 There are 8 hardware contexts. Supervisor and User FCs can have different contexts.
105
106 Segment map is 4096 entries, from bits 23-15 of the virtual address + 3 context bits.
107 Entries are 8 bits, which point to a page map entry group (PMEG), which is 16 consecutive
108 page table entries (32 KB of space).
109
110 Page map is 4096 entries each mapping a 2K page. There are 256 groups of 16 entries;
111 the PMEG points to these 256 groups. The page map contains a 20-bit page number,
112 which combines with the 11 low bits of the original address to get a 31-bit physical address.
113 The entry from 0-15 is picked with bits 15-11 of the original address.
114
115 Page map entries are written to the PMEG determined by their segment map entry; you must
116 set the segment map validly in order to write to the page map. This is how they get away
117 with having 16 MB of segment entries and only 8 MB of PMEGs.
118
119 See http://sunstuff.org/Sun-Hardware-Ref/s2hr/part2
120 ****************************************************************************/
121
122 #include "emu.h"
123 #include "cpu/m68000/m68000.h"
124 #include "machine/ram.h"
125 #include "machine/am9513.h"
126 #include "machine/i82586.h"
127 #include "machine/mm58167.h"
128 #include "machine/z80scc.h"
129 #include "machine/bankdev.h"
130 #include "machine/input_merger.h"
131 #include "bus/rs232/rs232.h"
132 #include "screen.h"
133
134 #define SCC1_TAG "scc1"
135 #define SCC2_TAG "scc2"
136 #define RS232A_TAG "rs232a"
137 #define RS232B_TAG "rs232b"
138
139 // page table entry constants
140 #define PM_VALID (0x80000000) // page is valid
141 #define PM_PROTMASK (0x7e000000) // protection mask
142 #define PM_TYPEMASK (0x01c00000) // type mask
143 #define PM_ACCESSED (0x00200000) // accessed flag
144 #define PM_MODIFIED (0x00100000) // modified flag
145
146 class sun2_state : public driver_device
147 {
148 public:
sun2_state(const machine_config & mconfig,device_type type,const char * tag)149 sun2_state(const machine_config &mconfig, device_type type, const char *tag)
150 : driver_device(mconfig, type, tag)
151 , m_maincpu(*this, "maincpu")
152 , m_rom(*this, "bootprom")
153 , m_idprom(*this, "idprom")
154 , m_ram(*this, RAM_TAG)
155 , m_type0space(*this, "type0")
156 , m_type1space(*this, "type1")
157 , m_type2space(*this, "type2")
158 , m_type3space(*this, "type3")
159 , m_edlc(*this, "edlc")
160 , m_bw2_vram(*this, "bw2_vram")
161 { }
162
163 void sun2mbus(machine_config &config);
164 void sun2vme(machine_config &config);
165
166 private:
167 required_device<m68010_device> m_maincpu;
168 required_memory_region m_rom, m_idprom;
169 required_device<ram_device> m_ram;
170 required_device<address_map_bank_device> m_type0space, m_type1space, m_type2space, m_type3space;
171 optional_device<i82586_device> m_edlc;
172 required_shared_ptr<uint16_t> m_bw2_vram;
173
174 virtual void machine_start() override;
175 virtual void machine_reset() override;
176
177 uint16_t mmu_r(offs_t offset, uint16_t mem_mask = ~0);
178 void mmu_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
179 uint16_t tl_mmu_r(uint8_t fc, offs_t offset, uint16_t mem_mask);
180 void tl_mmu_w(uint8_t fc, offs_t offset, uint16_t data, uint16_t mem_mask);
181 uint16_t video_ctrl_r();
182 void video_ctrl_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
183 uint16_t ram_r(offs_t offset);
184 void ram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
185 uint8_t ethernet_r();
186 void ethernet_w(uint8_t data);
187 DECLARE_WRITE_LINE_MEMBER(ethernet_int_w);
188 uint16_t edlc_mmu_r(offs_t offset, uint16_t mem_mask);
189 void edlc_mmu_w(offs_t offset, uint16_t data, uint16_t mem_mask);
190
191 uint32_t bw2_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
192
193 void mbustype0space_map(address_map &map);
194 void mbustype1space_map(address_map &map);
195 void mbustype2space_map(address_map &map);
196 void mbustype3space_map(address_map &map);
197 void sun2_mem(address_map &map);
198 void edlc_mem(address_map &map);
199 void vmetype0space_map(address_map &map);
200 void vmetype1space_map(address_map &map);
201 void vmetype2space_map(address_map &map);
202 void vmetype3space_map(address_map &map);
203
204 uint16_t *m_rom_ptr, *m_ram_ptr;
205 uint8_t *m_idprom_ptr;
206 uint16_t m_diagreg, m_sysenable, m_buserror;
207 uint16_t m_context;
208 uint8_t m_segmap[8][512];
209 uint32_t m_pagemap[4097];
210 uint32_t m_ram_size, m_ram_size_words;
211 uint16_t m_bw2_ctrl;
212 uint8_t m_ethernet_status;
213 };
214
ram_r(offs_t offset)215 uint16_t sun2_state::ram_r(offs_t offset)
216 {
217 if (offset < m_ram_size_words) return m_ram_ptr[offset];
218 return 0xffff;
219 }
220
ram_w(offs_t offset,uint16_t data,uint16_t mem_mask)221 void sun2_state::ram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
222 {
223 if (offset < m_ram_size_words) COMBINE_DATA(&m_ram_ptr[offset]);
224 }
225
mmu_r(offs_t offset,uint16_t mem_mask)226 uint16_t sun2_state::mmu_r(offs_t offset, uint16_t mem_mask)
227 {
228 return tl_mmu_r(m_maincpu->get_fc(), offset, mem_mask);
229 }
230
tl_mmu_r(uint8_t fc,offs_t offset,uint16_t mem_mask)231 uint16_t sun2_state::tl_mmu_r(uint8_t fc, offs_t offset, uint16_t mem_mask)
232 {
233 if ((fc == 3) && !machine().side_effects_disabled())
234 {
235 if (offset & 0x4) // set for CPU space
236 {
237 switch (offset & 7)
238 {
239 case 4:
240 //printf("sun2: Read IDPROM @ %x (PC=%x)\n", offset<<1, m_maincpu->pc());
241 return m_idprom_ptr[(offset>>10) & 0x1f]<<8;
242
243 case 5:
244 //printf("sun2: Read diag reg\n");
245 return m_diagreg;
246
247 case 6:
248 //printf("sun2: Read bus error @ PC %x\n", m_maincpu->pc());
249 return m_buserror;
250
251 case 7:
252 //printf("sun2: Read sysenable\n");
253 return m_sysenable;
254 }
255 }
256 else // clear for MMU space
257 {
258 int page;
259
260 switch (offset & 3)
261 {
262 case 0: // page map
263 case 1:
264 page = m_segmap[m_context & 7][offset >> 14] << 4;
265 page += ((offset >> 10) & 0xf);
266
267 //printf("sun2: Read page map at %x (entry %d)\n", offset<<1, page);
268 if (offset & 1) // low-order 16 bits
269 {
270 return m_pagemap[page] & 0xffff;
271 }
272 return m_pagemap[page] >> 16;
273
274 case 2: // segment map
275 //printf("sun2: Read segment map at %x (entry %d, user ctx %d)\n", offset<<1, offset>>14, m_context & 7);
276 return m_segmap[m_context & 7][offset >> 14];
277
278 case 3: // context reg
279 //printf("sun2: Read context reg\n");
280 return m_context;
281 }
282 }
283 }
284
285 // boot mode?
286 if ((fc == M68K_FC_SUPERVISOR_PROGRAM) && !(m_sysenable & 0x80))
287 {
288 return m_rom_ptr[offset & 0x3fff];
289 }
290
291 // debugger hack
292 if (machine().side_effects_disabled() && (offset >= (0xef0000>>1)) && (offset <= (0xef8000>>1)))
293 {
294 return m_rom_ptr[offset & 0x3fff];
295 }
296
297 // it's translation time
298 uint8_t context = (fc & 4) ? ((m_context >> 8) & 7) : (m_context & 7);
299 uint8_t pmeg = m_segmap[context][offset >> 14];
300 uint32_t entry = (pmeg << 4) + ((offset >> 10) & 0xf);
301
302 // printf("sun2: Context = %d, pmeg = %d, offset >> 14 = %x, entry = %d, page = %d\n", context, pmeg, offset >> 14, entry, (offset >> 10) & 0xf);
303
304 if (m_pagemap[entry] & PM_VALID)
305 {
306 m_pagemap[entry] |= PM_ACCESSED;
307
308 // Sun2 implementations only use 12 bits from the page entry
309 uint32_t tmp = (m_pagemap[entry] & 0xfff) << 10;
310 tmp |= (offset & 0x3ff);
311
312 // if (!machine().side_effects_disabled())
313 // printf("sun2: Translated addr: %08x, type %d (page %d page entry %08x, orig virt %08x, FC %d)\n", tmp << 1, (m_pagemap[entry] >> 22) & 7, entry, m_pagemap[entry], offset<<1, fc);
314
315 switch ((m_pagemap[entry] >> 22) & 7)
316 {
317 case 0: // type 0 space
318 return m_type0space->read16(tmp, mem_mask);
319
320 case 1: // type 1 space
321 // EPROM space is special: the MMU has a trap door
322 // where the original bits of the virtual address are
323 // restored so that the entire 32K EPROM can be
324 // accessed via a 2K single page view. This isn't
325 // obvious in the sun2 manual, but the sun3 manual
326 // (sun3 has the same mechanism) explains it well.
327 // the 2/50 ROM tests this specifically at $EF0DF0.
328 if (m_idprom_ptr[1] == 0x02) // 2/50 VMEbus has EPROM at 0x7F0000
329 {
330 if ((tmp >= (0x7f0000>>1)) && (tmp <= (0x7f07ff>>1)))
331 {
332 return m_rom_ptr[offset & 0x3fff]; // the mask here is probably &0x7fff, change it if any 8KW (1.x?) romset shows up for a VME machine
333 }
334 }
335 else // Multibus has EPROM at 0x000000
336 {
337 if (tmp <= (0x7ff>>1))
338 {
339 return m_rom_ptr[offset & 0x7fff];
340 }
341 }
342
343 //printf("read device space @ %x\n", tmp<<1);
344 return m_type1space->read16(tmp, mem_mask);
345
346 case 2: // type 2 space
347 return m_type2space->read16(tmp, mem_mask);
348
349 case 3: // type 3 space
350 return m_type3space->read16(tmp, mem_mask);
351 }
352 }
353 else
354 {
355 if (!machine().side_effects_disabled()) printf("sun2: pagemap entry not valid!\n");
356 }
357
358 if (!machine().side_effects_disabled()) printf("sun2: Unmapped read @ %08x (FC %d, mask %04x, PC=%x, seg %x)\n", offset<<1, fc, mem_mask, m_maincpu->pc(), offset>>15);
359
360 return 0xffff;
361 }
362
mmu_w(offs_t offset,uint16_t data,uint16_t mem_mask)363 void sun2_state::mmu_w(offs_t offset, uint16_t data, uint16_t mem_mask)
364 {
365 tl_mmu_w(m_maincpu->get_fc(), offset, data, mem_mask);
366 }
367
tl_mmu_w(uint8_t fc,offs_t offset,uint16_t data,uint16_t mem_mask)368 void sun2_state::tl_mmu_w(uint8_t fc, offs_t offset, uint16_t data, uint16_t mem_mask)
369 {
370 //printf("sun2: Write %04x (FC %d, mask %04x, PC=%x) to %08x\n", data, fc, mem_mask, m_maincpu->pc(), offset<<1);
371
372 if (fc == 3)
373 {
374 if (offset & 0x4) // set for CPU space
375 {
376 switch (offset & 7)
377 {
378 case 4:
379 //printf("sun2: Write? IDPROM @ %x\n", offset<<1);
380 return;
381
382 case 5:
383 // XOR to match Table 2-1 in the 2/50 Field Service Manual
384 printf("sun2: CPU LEDs to %02x (PC=%x) => ", (data & 0xff) ^ 0xff, m_maincpu->pc());
385 m_diagreg = data & 0xff;
386 for (int i = 0; i < 8; i++)
387 {
388 if (m_diagreg & (1<<(7-i)))
389 {
390 printf("*");
391 }
392 else
393 {
394 printf("O");
395 }
396 }
397 printf("\n");
398 return;
399
400 case 6:
401 //printf("sun2: Write %04x to bus error not allowed\n", data);
402 return;
403
404 case 7:
405 //printf("sun2: Write %04x to system enable\n", data);
406 COMBINE_DATA(&m_sysenable);
407 return;
408 }
409 }
410 else // clear for MMU space
411 {
412 int page;
413
414 switch (offset & 3)
415 {
416 case 0: // page map
417 case 1:
418 page = m_segmap[m_context & 7][offset >> 14] << 4;
419 page += ((offset >> 10) & 0xf);
420
421 //printf("sun2: Write %04x to page map at %x (entry %d), ", data, offset<<1, page);
422 if (offset & 1) // low-order 16 bits
423 {
424 m_pagemap[page] &= 0xffff0000;
425 m_pagemap[page] |= data;
426 }
427 else
428 {
429 m_pagemap[page] &= 0x0000ffff;
430 m_pagemap[page] |= (data<<16);
431 }
432 //printf("entry now %08x (adr %08x PC=%x)\n", m_pagemap[page], (m_pagemap[page] & 0xfffff) << 11, m_maincpu->pc());
433 return;
434
435 case 2: // segment map
436 //printf("sun2: Write %02x to segment map at %x (entry %d, user ctx %d PC=%x)\n", data & 0xff, offset<<1, offset>>14, m_context & 7, m_maincpu->pc());
437 m_segmap[m_context & 7][offset >> 14] = data & 0xff;
438 return;
439
440 case 3: // context reg
441 //printf("sun2: Write %04x to context\n", data);
442 COMBINE_DATA(&m_context);
443 return;
444 }
445 }
446 }
447
448 // it's translation time
449 uint8_t context = (fc & 4) ? ((m_context >> 8) & 7) : (m_context & 7);
450 uint8_t pmeg = m_segmap[context][offset >> 14];
451 uint32_t entry = (pmeg << 4) + ((offset >> 10) & 0xf);
452
453 if (m_pagemap[entry] & PM_VALID)
454 {
455 m_pagemap[entry] |= (PM_ACCESSED | PM_MODIFIED);
456
457 // only 12 of the 20 bits in the page table entry are used on either Sun2 implementation
458 uint32_t tmp = (m_pagemap[entry] & 0xfff) << 10;
459 tmp |= (offset & 0x3ff);
460
461 //if (!machine().side_effects_disabled()) printf("sun2: Translated addr: %08x, type %d (page entry %08x, orig virt %08x)\n", tmp << 1, (m_pagemap[entry] >> 22) & 7, m_pagemap[entry], offset<<1);
462
463 switch ((m_pagemap[entry] >> 22) & 7)
464 {
465 case 0: // type 0
466 m_type0space->write16(tmp, data, mem_mask);
467 return;
468
469 case 1: // type 1
470 //printf("write device space @ %x\n", tmp<<1);
471 m_type1space->write16(tmp, data, mem_mask);
472 return;
473
474 case 2: // type 2
475 m_type2space->write16(tmp, data, mem_mask);
476 return;
477
478 case 3: // type 3
479 m_type3space->write16(tmp, data, mem_mask);
480 return;
481 }
482 }
483 else
484 {
485 if (!machine().side_effects_disabled()) printf("sun2: pagemap entry not valid!\n");
486 }
487
488 printf("sun2: Unmapped write %04x (FC %d, mask %04x, PC=%x) to %08x\n", data, fc, mem_mask, m_maincpu->pc(), offset<<1);
489 }
490
491 // BW2 video control
video_ctrl_r()492 uint16_t sun2_state::video_ctrl_r()
493 {
494 return m_bw2_ctrl;
495 }
496
video_ctrl_w(offs_t offset,uint16_t data,uint16_t mem_mask)497 void sun2_state::video_ctrl_w(offs_t offset, uint16_t data, uint16_t mem_mask)
498 {
499 //printf("sun2: BW2: %x to video_ctrl\n", data);
500 COMBINE_DATA(&m_bw2_ctrl);
501 }
502
503 // 82586 Ethernet Data Link Controller interface
ethernet_r()504 uint8_t sun2_state::ethernet_r()
505 {
506 return m_ethernet_status;
507 }
508
ethernet_w(uint8_t data)509 void sun2_state::ethernet_w(uint8_t data)
510 {
511 m_edlc->reset_w(!BIT(data, 7));
512 m_edlc->set_loopback(!BIT(data, 6)); // LBC on MB502
513 m_edlc->ca(BIT(data, 5));
514
515 m_ethernet_status = (data & 0xf0) | (m_ethernet_status & 0x0f);
516 m_maincpu->set_input_line(M68K_IRQ_3, BIT(m_ethernet_status, 0) && BIT(m_ethernet_status, 4) ? ASSERT_LINE : CLEAR_LINE);
517 }
518
WRITE_LINE_MEMBER(sun2_state::ethernet_int_w)519 WRITE_LINE_MEMBER(sun2_state::ethernet_int_w)
520 {
521 if (state)
522 {
523 m_ethernet_status |= 0x01;
524 if (BIT(m_ethernet_status, 4))
525 m_maincpu->set_input_line(M68K_IRQ_3, ASSERT_LINE);
526 }
527 else
528 {
529 m_ethernet_status &= 0xfe;
530 if (BIT(m_ethernet_status, 4))
531 m_maincpu->set_input_line(M68K_IRQ_3, CLEAR_LINE);
532 }
533 }
534
edlc_mmu_r(offs_t offset,uint16_t mem_mask)535 uint16_t sun2_state::edlc_mmu_r(offs_t offset, uint16_t mem_mask)
536 {
537 uint16_t result = tl_mmu_r(M68K_FC_SUPERVISOR_DATA, offset, (mem_mask >> 8) | (mem_mask << 8));
538 return (result >> 8) | (result << 8);
539 }
540
edlc_mmu_w(offs_t offset,uint16_t data,uint16_t mem_mask)541 void sun2_state::edlc_mmu_w(offs_t offset, uint16_t data, uint16_t mem_mask)
542 {
543 tl_mmu_w(M68K_FC_SUPERVISOR_DATA, offset, (data >> 8) | (data << 8), (mem_mask >> 8) | (mem_mask << 8));
544 }
545
sun2_mem(address_map & map)546 void sun2_state::sun2_mem(address_map &map)
547 {
548 map(0x000000, 0xffffff).rw(FUNC(sun2_state::mmu_r), FUNC(sun2_state::mmu_w));
549 }
550
edlc_mem(address_map & map)551 void sun2_state::edlc_mem(address_map &map)
552 {
553 map(0x000000, 0xffffff).rw(FUNC(sun2_state::edlc_mmu_r), FUNC(sun2_state::edlc_mmu_w));
554 }
555
556 // VME memory spaces
557 // type 0 device space
vmetype0space_map(address_map & map)558 void sun2_state::vmetype0space_map(address_map &map)
559 {
560 map(0x000000, 0x7fffff).rw(FUNC(sun2_state::ram_r), FUNC(sun2_state::ram_w));
561 }
562
563 // type 1 device space
vmetype1space_map(address_map & map)564 void sun2_state::vmetype1space_map(address_map &map)
565 {
566 map(0x000000, 0x01ffff).ram().share("bw2_vram");
567 map(0x020000, 0x020001).rw(FUNC(sun2_state::video_ctrl_r), FUNC(sun2_state::video_ctrl_w));
568 map(0x7f0000, 0x7f07ff).rom().region("bootprom", 0); // uses MMU loophole to read 32k from a 2k window
569 map(0x7f0800, 0x7f0800).mirror(0x7fe).rw(FUNC(sun2_state::ethernet_r), FUNC(sun2_state::ethernet_w)).cswidth(16);
570 // 7f1000-7f17ff: AM9518 encryption processor
571 //map(0x7f1800, 0x7f1800).rw(SCC1_TAG, FUNC(z80scc_device::cb_r), FUNC(z80scc_device::cb_w));
572 //map(0x7f1802, 0x7f1802).rw(SCC1_TAG, FUNC(z80scc_device::db_r), FUNC(z80scc_device::db_w));
573 map(0x7f1804, 0x7f1805).nopr();
574 //map(0x7f1804, 0x7f1804).rw(SCC1_TAG, FUNC(z80scc_device::ca_r), FUNC(z80scc_device::ca_w));
575 //map(0x7f1806, 0x7f1806).rw(SCC1_TAG, FUNC(z80scc_device::da_r), FUNC(z80scc_device::da_w));
576 map(0x7f2000, 0x7f2000).rw(SCC2_TAG, FUNC(z80scc_device::cb_r), FUNC(z80scc_device::cb_w));
577 map(0x7f2002, 0x7f2002).rw(SCC2_TAG, FUNC(z80scc_device::db_r), FUNC(z80scc_device::db_w));
578 map(0x7f2004, 0x7f2004).rw(SCC2_TAG, FUNC(z80scc_device::ca_r), FUNC(z80scc_device::ca_w));
579 map(0x7f2006, 0x7f2006).rw(SCC2_TAG, FUNC(z80scc_device::da_r), FUNC(z80scc_device::da_w));
580 map(0x7f2800, 0x7f2803).mirror(0x7fc).rw("timer", FUNC(am9513_device::read16), FUNC(am9513_device::write16));
581 }
582
583 // type 2 device space
vmetype2space_map(address_map & map)584 void sun2_state::vmetype2space_map(address_map &map)
585 {
586 }
587
588 // type 3 device space
vmetype3space_map(address_map & map)589 void sun2_state::vmetype3space_map(address_map &map)
590 {
591 }
592
593 // Multibus memory spaces
594 // type 0 device space
mbustype0space_map(address_map & map)595 void sun2_state::mbustype0space_map(address_map &map)
596 {
597 map(0x000000, 0x3fffff).rw(FUNC(sun2_state::ram_r), FUNC(sun2_state::ram_w));
598 // 7f80000-7f807ff: Keyboard/mouse SCC8530
599 //map(0x7f8000, 0x7f8007).rw(SCC1_TAG, FUNC(z80scc_device::ab_dc_r), FUNC(z80scc_device::ab_dc_w)).umask16(0xff00);
600 map(0x700000, 0x71ffff).ram().share("bw2_vram");
601 map(0x781800, 0x781801).rw(FUNC(sun2_state::video_ctrl_r), FUNC(sun2_state::video_ctrl_w));
602 }
603
604 // type 1 device space
mbustype1space_map(address_map & map)605 void sun2_state::mbustype1space_map(address_map &map)
606 {
607 map(0x000000, 0x0007ff).rom().region("bootprom", 0); // uses MMU loophole to read 32k from a 2k window
608 // 001000-0017ff: AM9518 encryption processor
609 // 001800-001fff: Parallel port
610 map(0x002000, 0x0027ff).rw(SCC2_TAG, FUNC(z80scc_device::ab_dc_r), FUNC(z80scc_device::ab_dc_w)).umask16(0xff00);
611 map(0x002800, 0x002803).mirror(0x7fc).rw("timer", FUNC(am9513_device::read16), FUNC(am9513_device::write16));
612 map(0x003800, 0x00383f).mirror(0x7c0).rw("rtc", FUNC(mm58167_device::read), FUNC(mm58167_device::write)).umask16(0xff00); // 12 wait states generated by PAL16R6 (U415)
613 }
614
615 // type 2 device space (Multibus memory space)
mbustype2space_map(address_map & map)616 void sun2_state::mbustype2space_map(address_map &map)
617 {
618 }
619
620 // type 3 device space (Multibus I/O space)
mbustype3space_map(address_map & map)621 void sun2_state::mbustype3space_map(address_map &map)
622 {
623 }
624
bw2_update(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)625 uint32_t sun2_state::bw2_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
626 {
627 static const uint32_t palette[2] = { 0, 0xffffff };
628 uint8_t const *const m_vram = (uint8_t *)m_bw2_vram.target();
629
630 if (!(m_bw2_ctrl & 0x8000)) return 0;
631
632 for (int y = 0; y < 900; y++)
633 {
634 uint32_t *scanline = &bitmap.pix(y);
635 for (int x = 0; x < 1152/8; x++)
636 {
637 uint8_t const pixels = m_vram[(y * (1152/8)) + (BYTE_XOR_BE(x))];
638
639 *scanline++ = palette[BIT(pixels, 7)];
640 *scanline++ = palette[BIT(pixels, 6)];
641 *scanline++ = palette[BIT(pixels, 5)];
642 *scanline++ = palette[BIT(pixels, 4)];
643 *scanline++ = palette[BIT(pixels, 3)];
644 *scanline++ = palette[BIT(pixels, 2)];
645 *scanline++ = palette[BIT(pixels, 1)];
646 *scanline++ = palette[BIT(pixels, 0)];
647 }
648 }
649
650 return 0;
651 }
652
653 /* Input ports */
INPUT_PORTS_START(sun2)654 static INPUT_PORTS_START( sun2 )
655 INPUT_PORTS_END
656
657 void sun2_state::machine_start()
658 {
659 m_rom_ptr = (uint16_t *)m_rom->base();
660 m_idprom_ptr = (uint8_t *)m_idprom->base();
661 m_ram_ptr = (uint16_t *)m_ram->pointer();
662 m_ram_size = m_ram->size();
663 m_ram_size_words = m_ram_size >> 1;
664
665 m_ethernet_status = 0;
666 }
667
machine_reset()668 void sun2_state::machine_reset()
669 {
670 m_diagreg = 0;
671 m_sysenable = 0;
672 m_context = 0;
673 m_buserror = 0;
674 memset(m_segmap, 0, sizeof(m_segmap));
675 memset(m_pagemap, 0, sizeof(m_pagemap));
676
677 if (m_edlc.found())
678 ethernet_w(0);
679 }
680
sun2vme(machine_config & config)681 void sun2_state::sun2vme(machine_config &config)
682 {
683 /* basic machine hardware */
684 M68010(config, m_maincpu, 19.6608_MHz_XTAL / 2); // or 24_MHz_XTAL / 2 by jumper setting
685 m_maincpu->set_addrmap(AS_PROGRAM, &sun2_state::sun2_mem);
686
687 RAM(config, RAM_TAG).set_default_size("2M").set_extra_options("4M,6M,8M").set_default_value(0x00);
688
689 // MMU Type 0 device space
690 ADDRESS_MAP_BANK(config, "type0").set_map(&sun2_state::vmetype0space_map).set_options(ENDIANNESS_BIG, 16, 32, 0x1000000);
691
692 // MMU Type 1 device space
693 ADDRESS_MAP_BANK(config, "type1").set_map(&sun2_state::vmetype1space_map).set_options(ENDIANNESS_BIG, 16, 32, 0x1000000);
694
695 // MMU Type 2 device space
696 ADDRESS_MAP_BANK(config, "type2").set_map(&sun2_state::vmetype2space_map).set_options(ENDIANNESS_BIG, 16, 32, 0x1000000);
697
698 // MMU Type 3 device space
699 ADDRESS_MAP_BANK(config, "type3").set_map(&sun2_state::vmetype3space_map).set_options(ENDIANNESS_BIG, 16, 32, 0x1000000);
700
701 screen_device &bwtwo(SCREEN(config, "bwtwo", SCREEN_TYPE_RASTER));
702 bwtwo.set_screen_update(FUNC(sun2_state::bw2_update));
703 bwtwo.set_raw(100_MHz_XTAL, 1600, 0, 1152, 937, 0, 900);
704
705 I82586(config, m_edlc, 16_MHz_XTAL / 2);
706 m_edlc->set_addrmap(0, &sun2_state::edlc_mem);
707 m_edlc->out_irq_cb().set(FUNC(sun2_state::ethernet_int_w));
708
709 am9513a_device &timer(AM9513A(config, "timer", 19.6608_MHz_XTAL / 4));
710 timer.fout_cb().set("timer", FUNC(am9513_device::gate1_w));
711 timer.out1_cb().set_inputline(m_maincpu, M68K_IRQ_7);
712 timer.out2_cb().set("irq5", FUNC(input_merger_device::in_w<0>));
713 timer.out3_cb().set("irq5", FUNC(input_merger_device::in_w<1>));
714 timer.out4_cb().set("irq5", FUNC(input_merger_device::in_w<2>));
715 timer.out5_cb().set("irq5", FUNC(input_merger_device::in_w<3>));
716
717 INPUT_MERGER_ANY_HIGH(config, "irq5").output_handler().set_inputline(m_maincpu, M68K_IRQ_5); // 74LS05 open collectors
718
719 SCC8530N(config, SCC1_TAG, 19.6608_MHz_XTAL / 4);
720 scc8530_device& scc2(SCC8530N(config, SCC2_TAG, 19.6608_MHz_XTAL / 4));
721 scc2.out_txda_callback().set(RS232A_TAG, FUNC(rs232_port_device::write_txd));
722 scc2.out_txdb_callback().set(RS232B_TAG, FUNC(rs232_port_device::write_txd));
723 scc2.out_int_callback().set_inputline(m_maincpu, M68K_IRQ_6);
724
725 rs232_port_device &rs232a(RS232_PORT(config, RS232A_TAG, default_rs232_devices, nullptr));
726 rs232a.rxd_handler().set(SCC2_TAG, FUNC(z80scc_device::rxa_w));
727 rs232a.dcd_handler().set(SCC2_TAG, FUNC(z80scc_device::dcda_w));
728 rs232a.cts_handler().set(SCC2_TAG, FUNC(z80scc_device::ctsa_w));
729
730 rs232_port_device &rs232b(RS232_PORT(config, RS232B_TAG, default_rs232_devices, nullptr));
731 rs232b.rxd_handler().set(SCC2_TAG, FUNC(z80scc_device::rxb_w));
732 rs232b.dcd_handler().set(SCC2_TAG, FUNC(z80scc_device::dcdb_w));
733 rs232b.cts_handler().set(SCC2_TAG, FUNC(z80scc_device::ctsb_w));
734 }
735
sun2mbus(machine_config & config)736 void sun2_state::sun2mbus(machine_config &config)
737 {
738 /* basic machine hardware */
739 M68010(config, m_maincpu, 39.3216_MHz_XTAL / 4);
740 m_maincpu->set_addrmap(AS_PROGRAM, &sun2_state::sun2_mem);
741
742 RAM(config, RAM_TAG).set_default_size("2M").set_extra_options("4M").set_default_value(0x00);
743
744 // MMU Type 0 device space
745 ADDRESS_MAP_BANK(config, "type0").set_map(&sun2_state::mbustype0space_map).set_options(ENDIANNESS_BIG, 16, 32, 0x1000000);
746
747 // MMU Type 1 device space
748 ADDRESS_MAP_BANK(config, "type1").set_map(&sun2_state::mbustype1space_map).set_options(ENDIANNESS_BIG, 16, 32, 0x1000000);
749
750 // MMU Type 2 device space
751 ADDRESS_MAP_BANK(config, "type2").set_map(&sun2_state::mbustype2space_map).set_options(ENDIANNESS_BIG, 16, 32, 0x1000000);
752
753 // MMU Type 3 device space
754 ADDRESS_MAP_BANK(config, "type3").set_map(&sun2_state::mbustype3space_map).set_options(ENDIANNESS_BIG, 16, 32, 0x1000000);
755
756 screen_device &bwtwo(SCREEN(config, "bwtwo", SCREEN_TYPE_RASTER));
757 bwtwo.set_screen_update(FUNC(sun2_state::bw2_update));
758 bwtwo.set_raw(100_MHz_XTAL, 1600, 0, 1152, 937, 0, 900);
759 //bwtwo.set_raw(100_MHz_XTAL, 1600, 0, 1024, 1061, 0, 1024);
760
761 am9513a_device &timer(AM9513A(config, "timer", 39.3216_MHz_XTAL / 8));
762 timer.fout_cb().set("timer", FUNC(am9513_device::gate1_w));
763 timer.out1_cb().set_inputline(m_maincpu, M68K_IRQ_7);
764 timer.out2_cb().set("irq5", FUNC(input_merger_device::in_w<0>));
765 timer.out3_cb().set("irq5", FUNC(input_merger_device::in_w<1>));
766 timer.out4_cb().set("irq5", FUNC(input_merger_device::in_w<2>));
767 timer.out5_cb().set("irq5", FUNC(input_merger_device::in_w<3>));
768
769 INPUT_MERGER_ANY_HIGH(config, "irq5").output_handler().set_inputline(m_maincpu, M68K_IRQ_5); // 74LS05 open collectors
770
771 SCC8530N(config, SCC1_TAG, 39.3216_MHz_XTAL / 8);
772 scc8530_device& scc2(SCC8530N(config, SCC2_TAG, 39.3216_MHz_XTAL / 8));
773 scc2.out_txda_callback().set(RS232A_TAG, FUNC(rs232_port_device::write_txd));
774 scc2.out_txdb_callback().set(RS232B_TAG, FUNC(rs232_port_device::write_txd));
775 scc2.out_int_callback().set_inputline(m_maincpu, M68K_IRQ_6);
776
777 rs232_port_device &rs232a(RS232_PORT(config, RS232A_TAG, default_rs232_devices, nullptr));
778 rs232a.rxd_handler().set(SCC2_TAG, FUNC(z80scc_device::rxa_w));
779 rs232a.dcd_handler().set(SCC2_TAG, FUNC(z80scc_device::dcda_w));
780 rs232a.cts_handler().set(SCC2_TAG, FUNC(z80scc_device::ctsa_w));
781
782 rs232_port_device &rs232b(RS232_PORT(config, RS232B_TAG, default_rs232_devices, nullptr));
783 rs232b.rxd_handler().set(SCC2_TAG, FUNC(z80scc_device::rxb_w));
784 rs232b.dcd_handler().set(SCC2_TAG, FUNC(z80scc_device::dcdb_w));
785 rs232b.cts_handler().set(SCC2_TAG, FUNC(z80scc_device::ctsb_w));
786
787 MM58167(config, "rtc", 32.768_kHz_XTAL);
788 }
789
790 /* ROM definition */
791 ROM_START( sun2_120 ) // ROMs are located on the '501-1007' CPU PCB at locations B11 and B10; J400 is set to 1-2 for 27128 EPROMs and 3-4 for 27256 EPROMs
792 ROM_REGION16_BE(0x10000, "bootprom", ROMREGION_ERASEFF)
793 // There is an undumped revision 1.1.2, which uses 27256 EPROMs
794 ROM_SYSTEM_BIOS(0, "rev10f", "Bootrom Rev 1.0F")
795 ROMX_LOAD("1.0f.b11", 0x0000, 0x8000, CRC(8fb0050a) SHA1(399cdb894b2a66d847d76d8a5d266906fb1d3430), ROM_SKIP(1) | ROM_BIOS(0)) // actual rom stickers had fallen off
796 ROMX_LOAD("1.0f.b10", 0x0001, 0x8000, CRC(70de816d) SHA1(67e980497f463dbc529f64ec5f3e0046b3901b7e), ROM_SKIP(1) | ROM_BIOS(0)) // "
797 ROM_SYSTEM_BIOS(1, "revr", "Bootrom Rev R")
798 ROMX_LOAD("520-1102-03.b11", 0x0000, 0x4000, CRC(020bb0a8) SHA1(a7b60e89a40757975a5d345d57ea02781dea4f89), ROM_SKIP(1) | ROM_BIOS(1))
799 ROMX_LOAD("520-1101-03.b10", 0x0001, 0x4000, CRC(b97c61f7) SHA1(9f08fe232cfc3da48539fa66673fc1f89a362b1e), ROM_SKIP(1) | ROM_BIOS(1))
800 // There is an undumped revision Q, with roms:
801 //ROM_SYSTEM_BIOS( 8, "revq", "Bootrom Rev Q")
802 // ROMX_LOAD( "520-1104-02.b11", 0x0000, 0x4000, NO_DUMP, ROM_SKIP(1) | ROM_BIOS(8))
803 // ROMX_LOAD( "520-1103-02.b10", 0x0001, 0x4000, NO_DUMP, ROM_SKIP(1) | ROM_BIOS(8))
804 ROM_SYSTEM_BIOS( 2, "revn", "Bootrom Rev N") // SunOS 2.0 requires this bootrom version at a minimum; this version supports the sun-2 keyboard
805 ROMX_LOAD("revn.b11", 0x0000, 0x4000, CRC(b1e70965) SHA1(726b3ed9323750a1ae238cf6dccaed6ff5981ad1), ROM_SKIP(1) | ROM_BIOS(2)) // actual rom stickers had fallen off
806 ROMX_LOAD("revn.b10", 0x0001, 0x4000, CRC(95fd9242) SHA1(1eee2d291f4b18f6aafdde1a9521d88e454843b9), ROM_SKIP(1) | ROM_BIOS(2)) // "
807 ROM_SYSTEM_BIOS( 3, "revm", "Bootrom Rev M") // SunOS 1.0 apparently requires this bootrom revision; this version might only support the sun-1 keyboard?
808 ROMX_LOAD("sun2-revm-8.b11", 0x0000, 0x4000, CRC(98b8ae55) SHA1(55485f4d8fd1ebc218aa8527c8bb62752c34abf7), ROM_SKIP(1) | ROM_BIOS(3)) // handwritten label: "SUN2-RevM-8"
809 ROMX_LOAD("sun2-revm-0.b10", 0x0001, 0x4000, CRC(5117f431) SHA1(fce85c11ada1614152dde35bb329350f6fb2ecd9), ROM_SKIP(1) | ROM_BIOS(3)) // handwritten label: "SUN2-RevM-0"
810
811 ROM_REGION(0x20, "idprom", ROMREGION_ERASEFF)
812 ROM_LOAD("sun2120-idprom.bin", 0x000000, 0x000020, CRC(eec8cd1d) SHA1(6a78dc0ea6f9cc7687cffea754d65864fb751ebf))
813 ROM_END
814
815 ROM_START( sun2_50 )
816 ROM_REGION16_BE(0x8000, "bootprom", ROMREGION_ERASEFF)
817 // There is at least one undumped revision (Rev 1.1.2) which uses 27256 EPROMs; the sun2/50 board handles up to 27512 EPROMs
818 // bootrom rev Q
819 ROM_LOAD16_BYTE("250_q_8.rom", 0x0000, 0x4000, CRC(5bfacb5c) SHA1(ec7fb3fb0217b0138ba4748b7c79b8ff0cad896b))
820 ROM_LOAD16_BYTE("250_q_0.rom", 0x0001, 0x4000, CRC(2ee29abe) SHA1(82f52b9f25e92387329581f7c8ba50a171784968))
821
822 ROM_REGION(0x20, "idprom", ROMREGION_ERASEFF)
823 ROM_LOAD("sun250-idprom.bin", 0x000000, 0x000020, CRC(927744ab) SHA1(d29302b69128165e69dd3a79b8c8d45f2163b88a))
824 ROM_END
825
826 /* Driver */
827
828 // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
829 COMP( 1984, sun2_50, 0, 0, sun2vme, sun2, sun2_state, empty_init, "Sun Microsystems", "Sun 2/50", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
830 COMP( 1984, sun2_120, 0, 0, sun2mbus, sun2, sun2_state, empty_init, "Sun Microsystems", "Sun 2/120", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
831