Previous 15994 Revisions Next

r3085 Saturday 23rd August, 2008 at 05:18:46 UTC by R. Belmont
[MAC SE] Added preliminary ADB and ADB mouse emulation. System is now marked "working".
[docs]messnew.txt
[src/mess/drivers]mac.c
[src/mess/machine]mac.c

src/mess/machine/mac.c
r3084r3085
22
33   machine/mac.c
44
5   Mac hardware - Mac 128k, 512k, 512ke, Plus (SCSI, SCC, etc)
5   Mac hardware - Mac 128k, 512k, 512ke, Plus, SE, Classic, II (SCSI, SCC, ADB, etc)
66
77   Nate Woods
88   Ernesto Corvi
99   Raphael Nabet
10   R. Belmont
1011
1112   Mac Model Feature Summary:
1213
13                  CPU      FDC      Keyb   PRAM   ROMMir
14       - Mac 128k      68k      IWM      orig   orig   ???
15       - Mac 512k      68k      IWM      orig   orig   ???
16       - Mac 512ke   68k      IWM      orig   orig   ???
17       - Mac Plus      68k      IWM      orig   ext      no
18       - Mac SE      68k      IWM      ADB      ext      ???
19       - Mac Classic   68k      IWM      ADB      ext      ???
14                                CPU             FDC     Kbd/Mouse  PRAM   Video
15                 - Mac 128k   68k             IWM   orig       orig   Original
16                 - Mac 512k   68k             IWM   orig       orig   Original
17                 - Mac 512ke   68k             IWM   orig       orig   Original
18                 - Mac Plus   68k             IWM   orig       ext    Original
19                 - Mac SE   68k             IWM   MacII ADB  ext    Original
20                 - Mac Classic   68k             SWIM   ADB-???    ext    Original
21                 - Mac Portable   68k (16 MHz)    SWIM   ADB-PMU    PMU    640x480 B&W
22                 - PwrBook 100  68k (16 MHz)    SWIM   ADB-PMU    PMU    640x480 B&W
23       - Mac II       020             IWM   MacII ADB  ext    NuBus card
24       - Mac IIx      030             SWIM   MacII ADB  ext    NuBus card
25       - Mac IIfx     030             SWIM   ADB-IOP    ext    NuBus card
26       - Mac SE/30    030             SWIM    MacII ADB  ext    Internal fake NuBus card (need video declaration ROM!)
27       - Mac IIcx     030             SWIM   ADB-CUDA   ext    NuBus card
28       - Mac IIci     030             SWIM   ADB-CUDA   ext    Internal "RBV" type
2029
2130   Notes:
2231      - The Mac Plus boot code seems to check to see the extent of ROM
2332        mirroring to determine if SCSI is available.  If the ROM is mirrored,
2433        then SCSI is not available.  Thanks to R. Belmont for making this
2534        discovery.
35      - On the SE and most later Macs, the first access to 4xxxxx turns off the overlay.
36        However, the Mac II has the old-style VIA overlay control bit!
37      - The Mac II can have either a 68551 PMMU fitted or an Apple custom that handles 24 vs. 32
38        bit addressing mode.  The ROM is *not* 32-bit clean so Mac OS normally runs in 24 bit mode,
39        but A/UX can run 32.
40      - There are 5 known kinds of host-side ADB hardware:
41        * "Mac II ADB" used in the SE, II, IIx, IIcx, SE/30, IIci, Quadra 610, Quadra 650, Quadra 700,
42           Quadra 800, Centris 610 and Centris 650.  This is a dumb state machine using the VIA.
43        * "ADB-PMU" used in the Mac Portable and all 680x0-based PowerBooks.
44        * "ADB-EGRET" used in the IIsi, IIvi, IIvx, Classic II, LC, LC II, LC III, Performa 460,
45           and Performa 600.  This is a 68HC05 with a different internal ROM than CUDA.
46        * "ADB-IOP" (ADB driven by a 6502 coprocessor, similar to Lisa) used in the IIfx,
47          Quadra 900, and Quadra 950.
48        * "ADB-CUDA" (Apple's CUDA chip, which is a 68HC05 MCU) used in the Color Classic, LC 520,
49          LC 55x, LC 57x, LC 58x, Quadra 630, Quadra 660AV, Quadra 840AV, PowerMac 6100/7100/8100,
50          IIcx, IIci, and PowerMac 5200.
2651
2752   TODO:
53           - Mac Portable and PowerBook 100 are similar to this hardware, but we need ROMs!
2854      - Call the RTC timer
29
30      - Support Mac 128k, 512k (easy, we just need the ROM image)
31      - Support Mac SE, Classic (we need to find the ROMs and implement ADB;
32        SE FDHD and Classic require SIWM support, too)
55      - SE FDHD and Classic require SWIM support.  SWIM is 100% IWM compatible with 800k drives, but
56        becomes a different chip for 1.44MB.
3357      - Check that 0x600000-0x6fffff still address RAM when overlay bit is off
3458        (IM-III seems to say it does not on Mac 128k, 512k, and 512ke).
3559      - What on earth are 0x700000-0x7fffff mapped to ?
r3084r3085
6488#define LOG_MEMORY      0
6589#endif
6690
91#define LOG_ADB         0
92
93// ADB states
94#define ADB_STATE_NEW_COMMAND   (0)
95#define ADB_STATE_XFER_EVEN   (1)
96#define ADB_STATE_XFER_ODD   (2)
97#define ADB_STATE_IDLE      (3)
98
99// ADB commands
100#define ADB_CMD_RESET      (0)
101#define ADB_CMD_FLUSH      (1)
102
67103static TIMER_CALLBACK(mac_scanline_tick);
68static emu_timer *mac_scanline_timer;
104static TIMER_CALLBACK(mac_adb_tick);
105static emu_timer *mac_scanline_timer, *mac_adb_timer;
69106static int scan_keyboard(running_machine *machine);
70107static TIMER_CALLBACK(inquiry_timeout_func);
71108static void keyboard_receive(running_machine *machine, int val);
72109static READ8_HANDLER(mac_via_in_a);
73110static READ8_HANDLER(mac_via_in_b);
111static READ8_HANDLER(mac_adb_via_in_cb2);
74112static WRITE8_HANDLER(mac_via_out_a);
75113static WRITE8_HANDLER(mac_via_out_b);
114static WRITE8_HANDLER(mac_adb_via_out_cb2);
76115static WRITE8_HANDLER(mac_via_out_cb2);
77116static void mac_via_irq(running_machine *machine, int state);
78117static offs_t mac_dasm_override(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram);
r3084r3085
88127   mac_via_irq
89128};
90129
130static const struct via6522_interface mac_via6522_adb_intf =
131{
132   mac_via_in_a, mac_via_in_b,
133   NULL, NULL,
134   NULL, mac_adb_via_in_cb2,
135   mac_via_out_a, mac_via_out_b,
136   NULL, NULL,
137   NULL, mac_adb_via_out_cb2,
138   mac_via_irq
139};
140
91141/* tells which model is being emulated (set by macxxx_init) */
92142typedef enum
93143{
r3084r3085
100150
101151static UINT32 mac_overlay = 0;
102152static mac_model_t mac_model;
153static int mac_drive_select = 0;
103154
155// returns non-zero if this Mac has ADB
156static int has_adb(void)
157{
158   return mac_model >= MODEL_MAC_SE;
159}
104160
161// handle disk enable lines
162void mac_fdc_set_enable_lines(int enable_mask)
163{
164   if (mac_model < MODEL_MAC_SE)
165   {
166      sony_set_enable_lines(enable_mask);
167   }
168   else
169   {
170      if (enable_mask)
171      {
172         sony_set_enable_lines(mac_drive_select ? 1 : 2);
173      }
174      else
175      {
176         sony_set_enable_lines(enable_mask);
177      }
178   }
179}
105180
106181static void mac_install_memory(running_machine *machine, offs_t memory_begin, offs_t memory_end,
107182   offs_t memory_size, void *memory_data, int is_rom, int bank)
r3084r3085
11441219}
11451220
11461221/* *************************************************************************
1147 * ADB
1222 * ADB (Mac II-style)
11481223 * *************************************************************************/
11491224
1150static int adb_via_b3;
1225// Mac ADB state
1226static int adb_irq_pending, adb_waiting_cmd, adb_datasize, adb_buffer[8];
1227static int adb_state, adb_command, adb_send, adb_timer_ticks, adb_extclock, adb_direction;
1228static int adb_listenreg, adb_listenaddr;
11511229
1152static int has_adb(void)
1230// ADB mouse state
1231static int adb_mouseaddr = 3;
1232static int adb_lastmousex, adb_lastmousey;
1233
1234#if LOG_ADB
1235static const char *adb_statenames[4] = { "NEW", "EVEN", "ODD", "IDLE" };
1236#endif
1237
1238static void mac_adb_accummouse( running_machine *machine, UINT8 *MouseX, UINT8 *MouseY )
11531239{
1154   return mac_model >= MODEL_MAC_SE;
1240   int MouseCountX = 0, MouseCountY = 0;
1241   int NewX, NewY;
1242
1243   NewX = input_port_read(machine, "MOUSE2");
1244   NewY = input_port_read(machine, "MOUSE1");
1245
1246   /* see if it moved in the x coord */
1247   if (NewX != adb_lastmousex)
1248   {
1249      int diff = NewX - adb_lastmousex;
1250
1251      /* check for wrap */
1252      if (diff > 0x80)
1253         diff = 0x100-diff;
1254      if  (diff < -0x80)
1255         diff = -0x100-diff;
1256
1257      MouseCountX += diff;
1258      adb_lastmousex = NewX;
1259   }
1260
1261   /* see if it moved in the y coord */
1262   if (NewY != adb_lastmousey)
1263   {
1264      int diff = NewY - adb_lastmousey;
1265
1266      /* check for wrap */
1267      if (diff > 0x80)
1268         diff = 0x100-diff;
1269      if  (diff < -0x80)
1270         diff = -0x100-diff;
1271
1272      MouseCountY += diff;
1273      adb_lastmousey = NewY;
1274   }
1275
1276   *MouseX = (UINT8)MouseCountX;
1277   *MouseY = (UINT8)MouseCountY;
11551278}
11561279
1280static void mac_adb_talk(running_machine *machine)
1281{
1282   int addr, reg;
11571283
1284   addr = (adb_command>>4);
1285   reg = (adb_command & 3);
11581286
1287//   printf("Mac sent %x\n", adb_command);
1288
1289   if (adb_waiting_cmd)
1290   {
1291      switch ((adb_command>>2)&3)
1292      {
1293         case 0:
1294         case 1:
1295            switch (reg)
1296            {
1297               case ADB_CMD_RESET:
1298                  adb_direction = 0;
1299                  adb_send = 0;
1300                  break;
1301
1302               case ADB_CMD_FLUSH:
1303                  adb_direction = 0;
1304                  adb_send = 0;
1305                  break;
1306
1307               default:   // reserved/unused
1308                  break;
1309            }
1310            break;
1311
1312         case 2:   // listen
1313//            printf("ADB LISTEN: reg %x address %x\n", reg, addr);
1314            adb_direction = 1;   // input from Mac
1315            adb_listenreg = reg;
1316            adb_listenaddr = addr;
1317            break;
1318
1319         case 3: // talk
1320//            printf("ADB TALK: reg %x address %x\n", reg, addr);
1321
1322            adb_direction = 0;       // output to Mac
1323            if (addr == adb_mouseaddr)
1324            {
1325               UINT8 mouseX, mouseY;
1326
1327//               printf("Talking to mouse, register %x\n", reg);
1328
1329               switch (reg)
1330               {
1331                  // read mouse
1332                  case 0:   
1333                     mac_adb_accummouse(machine, &mouseX, &mouseY);
1334                     adb_buffer[0] = (input_port_read(machine, "MOUSE0") & 0x01) ? 0x00 : 0x80;
1335                     adb_buffer[0] |= mouseX & 0x7f;
1336                     adb_buffer[1] = mouseY & 0x7f;
1337                     adb_datasize = 2;
1338                     break;
1339
1340                  // get ID/handler
1341                  case 3:
1342                     adb_buffer[0] = 0x60 | ((adb_mouseaddr<<8)&0xf);   // SRQ enable, no exceptional event
1343                     adb_buffer[1] = 0x01;   // handler 1
1344                     adb_datasize = 2;
1345                     break;
1346
1347                  default:
1348                     break;
1349               }
1350            }
1351            break;
1352      }
1353
1354      adb_waiting_cmd = 0;
1355   }
1356   else
1357   {
1358      printf("Got LISTEN data %x for device %x reg %x\n", adb_command, adb_listenreg, adb_listenaddr);
1359   }
1360}
1361
1362static TIMER_CALLBACK(mac_adb_tick)
1363{
1364   // do one clock transition on CB1 to advance the VIA shifter
1365   adb_extclock ^= 1;
1366   via_set_input_cb1(machine, 0, adb_extclock);
1367   adb_extclock ^= 1;
1368   via_set_input_cb1(machine, 0, adb_extclock);
1369
1370   adb_timer_ticks--;
1371   if (!adb_timer_ticks)
1372   {
1373      timer_adjust_oneshot(mac_adb_timer, attotime_never, 0);
1374
1375      if (adb_direction)
1376      {
1377         mac_adb_talk(machine);
1378      }
1379   }
1380   else
1381   {
1382      timer_adjust_oneshot(mac_adb_timer, attotime_make(0, DOUBLE_TO_ATTOSECONDS(0.001)), 0);
1383   }
1384}
1385
1386static READ8_HANDLER(mac_adb_via_in_cb2)
1387{
1388   UINT8 ret;
1389
1390   ret = (adb_send & 0x80)>>7;
1391   adb_send <<= 1;
1392
1393//   printf("IN CB2 = %x\n", ret);
1394
1395   return ret;
1396}
1397
1398static WRITE8_HANDLER(mac_adb_via_out_cb2)
1399{
1400//   printf("OUT CB2 = %x\n", data);
1401   adb_command <<= 1;
1402   adb_command |= data & 1;
1403}
1404
11591405static void mac_adb_newaction(int state)
11601406{
1161   adb_via_b3 = 1;
1407   if (state != adb_state)
1408   {
1409      #if LOG_ADB
1410      printf("New ADB state: %s\n", adb_statenames[state]);
1411      #endif
1412
1413      adb_state = state;
1414      adb_timer_ticks = 8;
1415
1416      switch (state)
1417      {
1418         case ADB_STATE_NEW_COMMAND:
1419            adb_command = adb_send = 0;
1420            adb_direction = 1;   // Mac is shifting us a command
1421            adb_waiting_cmd = 1;   // we're going to get a command
1422            break;
1423
1424         case ADB_STATE_XFER_EVEN:
1425         case ADB_STATE_XFER_ODD:
1426            if (adb_datasize > 0)
1427            {
1428               int i;
1429
1430               // is something trying to send to the Mac?
1431               if (adb_direction == 0)
1432               {
1433                  // set up the byte
1434                  adb_send = adb_buffer[0];
1435                  adb_datasize--;
1436
1437                  // move down the rest of the buffer, if any
1438                  for (i = 0; i < adb_datasize; i++)
1439                  {
1440                     adb_buffer[i] = adb_buffer[i+1];
1441                  }
1442               }
1443            }
1444            else
1445            {
1446               adb_send = 0;
1447            }
1448            break;
1449
1450         case ADB_STATE_IDLE:
1451            break;
1452      }
1453
1454      // no matter what, generate 8 clocks (should this happen on IDLE?)
1455      timer_adjust_oneshot(mac_adb_timer, attotime_make(0, DOUBLE_TO_ATTOSECONDS(0.001)), 0);
1456   }
11621457}
11631458
1459static void adb_reset(void)
1460{
1461   adb_irq_pending = 0;      // no interrupt
1462   adb_timer_ticks = 0;
1463   adb_command = 0;
1464   adb_extclock = 0;
1465   adb_send = 0;
1466   adb_waiting_cmd = 0;
1467   adb_state = ADB_STATE_IDLE;
1468   adb_direction = 0;
1469   adb_datasize = 0;
11641470
1471   // mouse
1472   adb_mouseaddr = 3;
1473   adb_lastmousex = adb_lastmousey = 0;
1474}
11651475
11661476/* *************************************************************************
11671477 * VIA
r3084r3085
12091519
12101520   if (has_adb())
12111521   {
1212      if (adb_via_b3)
1522      val |= adb_state<<4;
1523
1524      if (!adb_irq_pending)
1525      {
12131526         val |= 0x08;
1527      }
12141528   }
12151529   else
12161530   {
r3084r3085
12321546   set_scc_waitrequest((data & 0x80) >> 7);
12331547   mac_set_screen_buffer((data & 0x40) >> 6);
12341548   sony_set_sel_line((data & 0x20) >> 5);
1235   mac_set_sound_buffer((data & 0x08) >> 3);
1549   if (mac_model == MODEL_MAC_SE)   // on SE this selects which floppy drive (0 = upper, 1 = lower)
1550   {
1551      mac_drive_select = ((data & 0x10) >> 4);
1552   }
1553
1554   if (mac_model < MODEL_MAC_SE)   // SE no longer has dual buffers
1555   {
1556      mac_set_sound_buffer((data & 0x08) >> 3);
1557   }
12361558   mac_set_volume(data & 0x07);
12371559
12381560   /* Early Mac models had VIA A4 control overlaying.  In the Mac SE (and
r3084r3085
12541576   rtc_rTCClk = new_rtc_rTCClk;
12551577
12561578   if (has_adb())
1579   {
12571580      mac_adb_newaction((data & 0x30) >> 4);
1581   }
12581582}
12591583
12601584static void mac_via_irq(running_machine *machine, int state)
r3084r3085
13181642   /* setup sound */
13191643   mac_set_sound_buffer(0);
13201644
1645   if (has_adb())
1646   {
1647      adb_reset();
1648
1649      mac_adb_timer = timer_alloc(mac_adb_tick, NULL);
1650      timer_adjust_oneshot(mac_adb_timer, attotime_never, 0);
1651   }
1652
13211653   if (mac_model == MODEL_MAC_SE)
1654   {
13221655      timer_set(attotime_zero, NULL, 0, set_memory_overlay_callback);
1656   }
13231657
13241658   mac_scanline_timer = timer_alloc(mac_scanline_tick, NULL);
13251659   timer_adjust_oneshot(mac_scanline_timer, video_screen_get_time_until_pos(machine->primary_screen, 0, 0), 0);
r3084r3085
13511685   set_memory_overlay(machine, 1);
13521686
13531687   /* configure via */
1354   via_config(0, &mac_via6522_intf);
1688   if (has_adb())
1689   {
1690      via_config(0, &mac_via6522_adb_intf);
1691   }
1692   else
1693   {
1694      via_config(0, &mac_via6522_intf);
1695   }
13551696   via_set_clock(0, 1000000);   /* 6522 = 1 Mhz, 6522a = 2 Mhz */
13561697
13571698   /* setup keyboard */
src/mess/drivers/mac.c
r3084r3085
8383static const applefdc_interface mac_iwm_interface =
8484{
8585   sony_set_lines,
86   sony_set_enable_lines,
86   mac_fdc_set_enable_lines,
8787
8888   sony_read_data,
8989   sony_write_data,
r3084r3085
378378COMP( 1984,   mac512k,  mac128k,   0,   mac512ke, macplus,  mac128k512k,   mac512k,   "Apple Computer",   "Macintosh 512k",  GAME_NOT_WORKING )
379379COMP( 1986,   mac512ke, macplus,  0,      mac512ke, macplus,  mac512ke,      mac512k,   "Apple Computer",   "Macintosh 512ke", 0 )
380380COMP( 1986,   macplus,  0,      0,   macplus,  macplus,  macplus,      macplus,   "Apple Computer",   "Macintosh Plus",  0 )
381COMP( 1987,   macse,    0,      0,   macplus,  macplus,  macse,          macse,      "Apple Computer",   "Macintosh SE",  GAME_NOT_WORKING )
381COMP( 1987,   macse,    0,      0,   macplus,  macplus,  macse,          macse,      "Apple Computer",   "Macintosh SE",  0 )
382382COMP( 1990,   macclasc, 0,      0,   macplus,  macplus,  macclassic,          macse,      "Apple Computer",   "Macintosh Classic",  GAME_NOT_WORKING )
383383
384384
docs/messnew.txt
r3084r3085
2424- [IBM5170] Added support for the 8042 keyboard controller dumped
2525  by Kevtris.  [Wilbert Pol]
2626
27- [Mac SE] Added preliminary ADB mouse emulation, system is now working [R.
28  Belmont]
29
2730- [MSX Family] Fixed cartridge loading. (part of bug #1603)  [Wilbert
2831  Pol]
2932

Previous 15994 Revisions Next


© 1998-2018 The MESS Team