- added some 68040 instructions: CINV, CPUSH, MOVE16 (Ax)+,(Ay)+, MOVEC regs,

and FPU state frames; enough to boot MacOS
- CPU type can be selected in GTK prefs editor
This commit is contained in:
cebix 1999-10-28 15:33:26 +00:00
parent 1a20b690a6
commit c31d1bd2af
15 changed files with 228 additions and 86 deletions

View File

@ -7,6 +7,7 @@ V0.8 -
- fixed one possible source of "unimplemented trap" errors on MacOS
bootup
- medium removal is allowed in CDROMExit()
- added (incomplete) emulation of 68040 instructions
- extfs.cpp: fixed bug with fsResolveWDCB in fs_get_wd_info()
- Unix: added support for ESD audio output; merged with OSS audio
and put in a new "audio_oss_esd.cpp" file which is also used under

View File

@ -35,7 +35,7 @@ Framebuffer device specifications.
.I ~/.basilisk_ii_prefs
User-specific configuration file.
.TP
.I ~/.basilisk_ii_nvram
.I ~/.basilisk_ii_xpram
Contents of Mac non-volatile RAM.
.SH BUGS
Several. See the included "TODO" file.

View File

@ -156,7 +156,7 @@ int main(int argc, char **argv)
QuitEmulator();
}
#if ENABLE_XF86_DGA
#if ENABLE_XF86_DGA && !ENABLE_MON
// Fork out, so we can return from fullscreen mode when things get ugly
XF86DGAForkApp(DefaultScreen(x_display));
#endif

View File

@ -933,11 +933,12 @@ static GtkWidget *w_keycode_file;
static void mn_modelid_5(...) {PrefsReplaceInt32("modelid", 5);}
static void mn_modelid_14(...) {PrefsReplaceInt32("modelid", 14);}
// "FPU Emulation" button toggled
static void tb_fpu(GtkWidget *widget)
{
PrefsReplaceBool("fpu", GTK_TOGGLE_BUTTON(widget)->active);
}
// CPU/FPU type
static void mn_cpu_68020(...) {PrefsReplaceInt32("cpu", 2); PrefsReplaceBool("fpu", false);}
static void mn_cpu_68020_fpu(...) {PrefsReplaceInt32("cpu", 2); PrefsReplaceBool("fpu", true);}
static void mn_cpu_68030(...) {PrefsReplaceInt32("cpu", 3); PrefsReplaceBool("fpu", false);}
static void mn_cpu_68030_fpu(...) {PrefsReplaceInt32("cpu", 3); PrefsReplaceBool("fpu", true);}
static void mn_cpu_68040(...) {PrefsReplaceInt32("cpu", 4); PrefsReplaceBool("fpu", true);}
// "Use Raw Keycodes" button toggled
static void tb_keycodes(GtkWidget *widget)
@ -1008,7 +1009,7 @@ static void create_memory_pane(GtkWidget *top)
gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
static const opt_desc options[] = {
static const opt_desc model_options[] = {
{STR_MODELID_5_LAB, GTK_SIGNAL_FUNC(mn_modelid_5)},
{STR_MODELID_14_LAB, GTK_SIGNAL_FUNC(mn_modelid_14)},
{0, NULL}
@ -1018,12 +1019,28 @@ static void create_memory_pane(GtkWidget *top)
case 5: active = 0; break;
case 14: active = 1; break;
}
menu = make_option_menu(box, STR_MODELID_CTRL, options, active);
make_option_menu(box, STR_MODELID_CTRL, model_options, active);
static const opt_desc cpu_options[] = {
{STR_CPU_68020_LAB, GTK_SIGNAL_FUNC(mn_cpu_68020)},
{STR_CPU_68020_FPU_LAB, GTK_SIGNAL_FUNC(mn_cpu_68020_fpu)},
{STR_CPU_68030_LAB, GTK_SIGNAL_FUNC(mn_cpu_68030)},
{STR_CPU_68030_FPU_LAB, GTK_SIGNAL_FUNC(mn_cpu_68030_fpu)},
{STR_CPU_68040_LAB, GTK_SIGNAL_FUNC(mn_cpu_68040)},
{0, NULL}
};
int cpu = PrefsFindInt32("cpu");
bool fpu = PrefsFindBool("fpu");
active = 0;
switch (cpu) {
case 2: active = fpu ? 1 : 0; break;
case 3: active = fpu ? 3 : 2; break;
case 4: active = 4;
}
make_option_menu(box, STR_CPU_CTRL, cpu_options, active);
w_rom_file = make_entry(box, STR_ROM_FILE_CTRL, "rom");
make_checkbox(box, STR_FPU_CTRL, "fpu", GTK_SIGNAL_FUNC(tb_fpu));
make_checkbox(box, STR_KEYCODES_CTRL, "keycodes", GTK_SIGNAL_FUNC(tb_keycodes));
w_keycode_file = make_entry(box, STR_KEYCODE_FILE_CTRL, "keycodefile");
}

View File

@ -175,8 +175,13 @@ enum {
STR_MODELID_CTRL,
STR_MODELID_5_LAB,
STR_MODELID_14_LAB,
STR_CPU_CTRL,
STR_CPU_68020_LAB,
STR_CPU_68020_FPU_LAB,
STR_CPU_68030_LAB,
STR_CPU_68030_FPU_LAB,
STR_CPU_68040_LAB,
STR_ROM_FILE_CTRL,
STR_FPU_CTRL,
// Mac window
STR_WINDOW_TITLE = 4000,

View File

@ -79,13 +79,19 @@ bool InitAll(void)
TwentyFourBitAddressing = true;
break;
case ROM_VERSION_II:
CPUType = 2;
CPUType = PrefsFindInt32("cpu");
if (CPUType < 2) CPUType = 2;
if (CPUType > 4) CPUType = 4;
FPUType = PrefsFindBool("fpu") ? 1 : 0;
if (CPUType == 4) FPUType = 1; // 68040 always with FPU
TwentyFourBitAddressing = true;
break;
case ROM_VERSION_32:
CPUType = 3;
CPUType = PrefsFindInt32("cpu");
if (CPUType < 2) CPUType = 2;
if (CPUType > 4) CPUType = 4;
FPUType = PrefsFindBool("fpu") ? 1 : 0;
if (CPUType == 4) FPUType = 1; // 68040 always with FPU
TwentyFourBitAddressing = false;
break;
}

View File

@ -49,12 +49,13 @@ prefs_desc common_prefs_items[] = {
{"serialb", TYPE_STRING, false}, // Device name of Mac serial port B (serial_*.cpp)
{"ether", TYPE_STRING, false}, // Device name of Mac ethernet adapter (ether_*.cpp)
{"rom", TYPE_STRING, false}, // Path of ROM file (main_*.cpp)
{"bootdrive", TYPE_INT16, false}, // Boot drive number (main_*.cpp)
{"bootdriver", TYPE_INT16, false}, // Boot driver number (main_*.cpp)
{"bootdrive", TYPE_INT16, false}, // Boot drive number (main.cpp)
{"bootdriver", TYPE_INT16, false}, // Boot driver number (main.cpp)
{"ramsize", TYPE_INT32, false}, // Size of Mac RAM in bytes (main_*.cpp)
{"frameskip", TYPE_INT32, false}, // Number of frames to skip in refreshed video modes (video_*.cpp)
{"modelid", TYPE_INT32, false}, // Mac Model ID (Gestalt Model ID minus 6) (rom_patches.cpp)
{"fpu", TYPE_BOOLEAN, false}, // Enable FPU emulation (main_*.cpp)
{"cpu", TYPE_INT32, false}, // CPU type (0 = 68000, 1 = 68010 etc.) (main.cpp)
{"fpu", TYPE_BOOLEAN, false}, // Enable FPU emulation (main.cpp)
{"nocdrom", TYPE_BOOLEAN, false}, // Don't install CD-ROM driver (cdrom.cpp/rom_patches.cpp)
{"nosound", TYPE_BOOLEAN, false}, // Don't enable sound output (audio_*.cpp)
{"nogui", TYPE_BOOLEAN, false}, // Disable GUI (main_*.cpp)
@ -90,6 +91,7 @@ void PrefsInit(void)
PrefsAddInt32("ramsize", 8 * 1024 * 1024);
PrefsAddInt32("frameskip", 6);
PrefsAddInt32("modelid", 5); // Mac IIci
PrefsAddInt32("cpu", 3); // 68030
PrefsAddBool("fpu", false);
PrefsAddBool("nocdrom", false);
PrefsAddBool("nosound", false);

View File

@ -131,6 +131,7 @@ int main(int argc, char **argv)
case '2': cpulevel = 2; break;
case '3': cpulevel = 3; break;
case '4': cpulevel = 4; break;
case '5': cpulevel = 5; break;
default: abort();
}
getnextch();

View File

@ -71,6 +71,7 @@
#include "memory.h"
#include "readcpu.h"
#include "newcpu.h"
#include "main.h"
#define DEBUG 0
#include "debug.h"
@ -1234,31 +1235,40 @@ void fsave_opp(uae_u32 opcode)
return;
}
// Put 28 byte IDLE frame.
// NOTE!!! IDLE frame is only 4 bytes on a 68040!!
if (incr < 0) {
D(bug("fsave_opp pre-decrement\r\n"));
ad -= 4;
// What's this? Some BIU flags, or (incorrectly placed) command/condition?
put_long (ad, 0x70000000);
for (i = 0; i < 5; i++) {
ad -= 4;
put_long (ad, 0x00000000);
if (CPUType == 4) {
// Put 4 byte 68040 IDLE frame.
if (incr < 0) {
ad -= 4;
put_long (ad, 0x41000000);
} else {
put_long (ad, 0x41000000);
ad += 4;
}
ad -= 4;
put_long (ad, 0x1f180000); // IDLE, vers 1f
} else {
put_long (ad, 0x1f180000); // IDLE, vers 1f
ad += 4;
for (i = 0; i < 5; i++) {
put_long (ad, 0x00000000);
ad += 4;
}
// What's this? Some BIU flags, or (incorrectly placed) command/condition?
put_long (ad, 0x70000000);
ad += 4;
}
} else {
// Put 28 byte 68881 IDLE frame.
if (incr < 0) {
D(bug("fsave_opp pre-decrement\r\n"));
ad -= 4;
// What's this? Some BIU flags, or (incorrectly placed) command/condition?
put_long (ad, 0x70000000);
for (i = 0; i < 5; i++) {
ad -= 4;
put_long (ad, 0x00000000);
}
ad -= 4;
put_long (ad, 0x1f180000); // IDLE, vers 1f
} else {
put_long (ad, 0x1f180000); // IDLE, vers 1f
ad += 4;
for (i = 0; i < 5; i++) {
put_long (ad, 0x00000000);
ad += 4;
}
// What's this? Some BIU flags, or (incorrectly placed) command/condition?
put_long (ad, 0x70000000);
ad += 4;
}
}
if ((opcode & 0x38) == 0x18) {
m68k_areg (regs, opcode & 7) = ad; // Never executed on a 68881
D(bug("PROBLEM: fsave_opp post-increment\r\n"));
@ -1269,7 +1279,7 @@ void fsave_opp(uae_u32 opcode)
}
}
// FSAVE has no pre-decrement
// FRESTORE has no pre-decrement
void frestore_opp(uae_u32 opcode)
{
uae_u32 ad;
@ -1284,37 +1294,70 @@ void frestore_opp(uae_u32 opcode)
return;
}
if (incr < 0) {
D(bug("PROBLEM: frestore_opp incr < 0\r\n"));
// this may be wrong, but it's never called.
ad -= 4;
d = get_long (ad);
if ((d & 0xff000000) != 0) {
if ((d & 0x00ff0000) == 0x00180000)
ad -= 6 * 4;
else if ((d & 0x00ff0000) == 0x00380000)
ad -= 14 * 4;
else if ((d & 0x00ff0000) == 0x00b40000)
ad -= 45 * 4;
if (CPUType == 4) {
// 68040
if (incr < 0) {
D(bug("PROBLEM: frestore_opp incr < 0\r\n"));
// this may be wrong, but it's never called.
ad -= 4;
d = get_long (ad);
if ((d & 0xff000000) != 0) { // Not a NULL frame?
if ((d & 0x00ff0000) == 0) { // IDLE
D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4));
} else if ((d & 0x00ff0000) == 0x00300000) { // UNIMP
D(bug("PROBLEM: frestore_opp found UNIMP frame at %X\r\n",ad-4));
ad -= 44;
} else if ((d & 0x00ff0000) == 0x00600000) { // BUSY
D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4));
ad -= 92;
}
}
} else {
d = get_long (ad);
D(bug("frestore_opp frame at %X = %X\r\n",ad,d));
ad += 4;
if ((d & 0xff000000) != 0) { // Not a NULL frame?
if ((d & 0x00ff0000) == 0) { // IDLE
D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4));
} else if ((d & 0x00ff0000) == 0x00300000) { // UNIMP
D(bug("PROBLEM: frestore_opp found UNIMP frame at %X\r\n",ad-4));
ad += 44;
} else if ((d & 0x00ff0000) == 0x00600000) { // BUSY
D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4));
ad += 92;
}
}
}
} else {
d = get_long (ad);
D(bug("frestore_opp frame at %X = %X\r\n",ad,d));
ad += 4;
if ((d & 0xff000000) != 0) { // Not a NULL frame?
if ((d & 0x00ff0000) == 0x00180000) { // IDLE
D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4));
ad += 6 * 4;
} else if ((d & 0x00ff0000) == 0x00380000) {// UNIMP? shouldn't it be 3C?
ad += 14 * 4;
D(bug("PROBLEM: frestore_opp found UNIMP? frame at %X\r\n",ad-4));
} else if ((d & 0x00ff0000) == 0x00b40000) {// BUSY
D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4));
ad += 45 * 4;
} else {
// 68881
if (incr < 0) {
D(bug("PROBLEM: frestore_opp incr < 0\r\n"));
// this may be wrong, but it's never called.
ad -= 4;
d = get_long (ad);
if ((d & 0xff000000) != 0) {
if ((d & 0x00ff0000) == 0x00180000)
ad -= 6 * 4;
else if ((d & 0x00ff0000) == 0x00380000)
ad -= 14 * 4;
else if ((d & 0x00ff0000) == 0x00b40000)
ad -= 45 * 4;
}
} else {
d = get_long (ad);
D(bug("frestore_opp frame at %X = %X\r\n",ad,d));
ad += 4;
if ((d & 0xff000000) != 0) { // Not a NULL frame?
if ((d & 0x00ff0000) == 0x00180000) { // IDLE
D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4));
ad += 6 * 4;
} else if ((d & 0x00ff0000) == 0x00380000) {// UNIMP? shouldn't it be 3C?
ad += 14 * 4;
D(bug("PROBLEM: frestore_opp found UNIMP? frame at %X\r\n",ad-4));
} else if ((d & 0x00ff0000) == 0x00b40000) {// BUSY
D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4));
ad += 45 * 4;
}
}
}
}

View File

@ -59,7 +59,7 @@ static void read_counts (void)
if (file) {
fscanf (file, "Total: %lu\n", &total);
while (fscanf (file, "%lx: %lu %s\n", &opcode, &count, name) == 3) {
opcode_next_clev[nr] = 3;
opcode_next_clev[nr] = 4;
opcode_last_postfix[nr] = -1;
opcode_map[nr++] = opcode;
counts[opcode] = count;
@ -72,7 +72,7 @@ static void read_counts (void)
if (table68k[opcode].handler == -1 && table68k[opcode].mnemo != i_ILLG
&& counts[opcode] == 0)
{
opcode_next_clev[nr] = 3;
opcode_next_clev[nr] = 4;
opcode_last_postfix[nr] = -1;
opcode_map[nr++] = opcode;
counts[opcode] = count;
@ -1517,6 +1517,8 @@ static void gen_opcode (unsigned long int opcode)
printf ("\tif ((format & 0xF000) == 0x0000) { break; }\n");
printf ("\telse if ((format & 0xF000) == 0x1000) { ; }\n");
printf ("\telse if ((format & 0xF000) == 0x2000) { m68k_areg(regs, 7) += 4; break; }\n");
printf ("\telse if ((format & 0xF000) == 0x3000) { m68k_areg(regs, 7) += 4; break; }\n");
printf ("\telse if ((format & 0xF000) == 0x7000) { m68k_areg(regs, 7) += 52; break; }\n");
printf ("\telse if ((format & 0xF000) == 0x8000) { m68k_areg(regs, 7) += 50; break; }\n");
printf ("\telse if ((format & 0xF000) == 0x9000) { m68k_areg(regs, 7) += 12; break; }\n");
printf ("\telse if ((format & 0xF000) == 0xa000) { m68k_areg(regs, 7) += 24; break; }\n");
@ -2442,6 +2444,24 @@ static void gen_opcode (unsigned long int opcode)
swap_opcode ();
printf ("\tfrestore_opp(opcode);\n");
break;
case i_CINVL:
case i_CINVP:
case i_CINVA:
case i_CPUSHL:
case i_CPUSHP:
case i_CPUSHA:
break;
case i_MOVE16:
printf ("\tuaecptr mems = m68k_areg(regs, srcreg) & ~15, memd;\n");
printf ("\tdstreg = (%s >> 12) & 7;\n", gen_nextiword());
printf ("\tmemd = m68k_areg(regs, dstreg) & ~15;\n");
printf ("\tput_long(memd, get_long(mems));\n");
printf ("\tput_long(memd+4, get_long(mems+4));\n");
printf ("\tput_long(memd+8, get_long(mems+8));\n");
printf ("\tput_long(memd+12, get_long(mems+12));\n");
printf ("\tm68k_areg(regs, srcreg) += 16;\n");
printf ("\tm68k_areg(regs, dstreg) += 16;\n");
break;
case i_MMUOP:
genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0);
sync_m68k_pc ();
@ -2620,9 +2640,9 @@ static void generate_func (void)
using_prefetch = 0;
using_exception_3 = 0;
for (i = 0; i < 5; i++) {
cpu_level = 3 - i;
if (i == 4) {
for (i = 0; i < 6; i++) {
cpu_level = 4 - i;
if (i == 5) {
cpu_level = 0;
using_prefetch = 1;
using_exception_3 = 1;

View File

@ -123,11 +123,23 @@ static void build_cpufunctbl (void)
{
int i;
unsigned long opcode;
int cpu_level = (FPUType ? 3 : CPUType >= 2 ? 2 : CPUType == 1 ? 1 : 0);
struct cputbl *tbl = (cpu_level == 3 ? op_smalltbl_0
: cpu_level == 2 ? op_smalltbl_1
: cpu_level == 1 ? op_smalltbl_2
: op_smalltbl_3);
int cpu_level = 0; // 68000 (default)
if (CPUType == 4)
cpu_level = 4; // 68040 with FPU
else {
if (FPUType)
cpu_level = 3; // 68020 with FPU
else if (CPUType >= 2)
cpu_level = 2; // 68020
else if (CPUType == 1)
cpu_level = 1;
}
struct cputbl *tbl = (
cpu_level == 4 ? op_smalltbl_0
: cpu_level == 3 ? op_smalltbl_1
: cpu_level == 2 ? op_smalltbl_2
: cpu_level == 1 ? op_smalltbl_3
: op_smalltbl_4);
for (opcode = 0; opcode < 65536; opcode++)
cpufunctbl[cft_map (opcode)] = op_illg_1;
@ -710,7 +722,7 @@ static void Interrupt(int nr)
regs.spcflags |= SPCFLAG_INT;
}
static int caar, cacr;
static int caar, cacr, tc, itt0, itt1, dtt0, dtt1;
void m68k_move2c (int regno, uae_u32 *regp)
{
@ -721,6 +733,11 @@ void m68k_move2c (int regno, uae_u32 *regp)
case 0: regs.sfc = *regp & 7; break;
case 1: regs.dfc = *regp & 7; break;
case 2: cacr = *regp & 0x3; break; /* ignore C and CE */
case 3: tc = *regp & 0xc000; break;
case 4: itt0 = *regp & 0xffffe364; break;
case 5: itt1 = *regp & 0xffffe364; break;
case 6: dtt0 = *regp & 0xffffe364; break;
case 7: dtt1 = *regp & 0xffffe364; break;
case 0x800: regs.usp = *regp; break;
case 0x801: regs.vbr = *regp; break;
case 0x802: caar = *regp &0xfc; break;
@ -741,6 +758,11 @@ void m68k_movec2 (int regno, uae_u32 *regp)
case 0: *regp = regs.sfc; break;
case 1: *regp = regs.dfc; break;
case 2: *regp = cacr; break;
case 3: *regp = tc; break;
case 4: *regp = itt0; break;
case 5: *regp = itt1; break;
case 6: *regp = dtt0; break;
case 7: *regp = dtt1; break;
case 0x800: *regp = regs.usp; break;
case 0x801: *regp = regs.vbr; break;
case 0x802: *regp = caar; break;
@ -1070,6 +1092,7 @@ unsigned long REGPARAM2 op_illg (uae_u32 opcode)
return 4;
}
printf("Illegal instruction %04x at %08lx\n", opcode, pc); //!!
if ((opcode & 0xF000) == 0xF000) {
Exception(0xB,0);
return 4;

View File

@ -130,6 +130,15 @@ struct mnemolookup lookuptab[] = {
{ i_FBcc, "FBcc" },
{ i_FSAVE, "FSAVE" },
{ i_FRESTORE, "FRESTORE" },
{ i_CINVL, "CINVL" },
{ i_CINVP, "CINVP" },
{ i_CINVA, "CINVA" },
{ i_CPUSHL, "CPUSHL" },
{ i_CPUSHP, "CPUSHP" },
{ i_CPUSHA, "CPUSHA" },
{ i_MOVE16, "MOVE16" },
{ i_MMUOP, "MMUOP" },
{ i_ILLG, "" },
};

View File

@ -31,6 +31,7 @@ ENUMDECL {
i_BFTST,i_BFEXTU,i_BFCHG,i_BFEXTS,i_BFCLR,i_BFFFO,i_BFSET,i_BFINS,
i_PACK, i_UNPK, i_TAS, i_BKPT, i_CALLM, i_RTM, i_TRAPcc, i_MOVES,
i_FPP, i_FDBcc, i_FScc, i_FTRAPcc, i_FBcc, i_FSAVE, i_FRESTORE,
i_CINVL, i_CINVP, i_CINVA, i_CPUSHL, i_CPUSHP, i_CPUSHA, i_MOVE16,
i_MMUOP
} ENUMNAME (instrmnem);

View File

@ -27,10 +27,12 @@
%
% Fields on a line:
% 16 chars bitpattern :
% CPU level / privildge level :
% CPU level / privilege level :
% CPU level 0: 68000
% 1: 68010
% 2: 68020
% 3: 68020/68881
% 4: 68040
% privilege level 0: not privileged
% 1: unprivileged only on 68000 (check regs.s)
% 2: privileged (check regs.s)
@ -239,4 +241,11 @@
1111 0011 00ss sSSS:32:?????:?????:20: FSAVE s[!Dreg,Areg,Aipi,Immd,PC8r,PC16]
1111 0011 01ss sSSS:32:?????:?????:10: FRESTORE s[!Dreg,Areg,Apdi,Immd]
1111 0000 00ss sSSS:40:?????:?????:11: MMUOP #1,s
% 68040 instructions
1111 0100 ii00 1rrr:42:-----:-----:02: CINVL #i,Ar
1111 0100 ii01 0rrr:42:-----:-----:02: CINVP #i,Ar
1111 0100 ii01 1rrr:42:-----:-----:00: CINVA #i
1111 0100 ii10 1rrr:42:-----:-----:02: CPUSHL #i,Ar
1111 0100 ii11 0rrr:42:-----:-----:02: CPUSHP #i,Ar
1111 0100 ii11 1rrr:42:-----:-----:00: CPUSHA #i
1111 0110 0010 0rrr:40:-----:-----:12: MOVE16 ArP,ARP

View File

@ -190,8 +190,13 @@ user_string_def common_strings[] = {
{STR_MODELID_CTRL, "Mac Model ID"},
{STR_MODELID_5_LAB, "Mac IIci (MacOS 7.x)"},
{STR_MODELID_14_LAB, "Quadra 900 (MacOS 8.x)"},
{STR_CPU_CTRL, "CPU Type"},
{STR_CPU_68020_LAB, "68020"},
{STR_CPU_68020_FPU_LAB, "68020 with FPU"},
{STR_CPU_68030_LAB, "68030"},
{STR_CPU_68030_FPU_LAB, "68030 with FPU"},
{STR_CPU_68040_LAB, "68040"},
{STR_ROM_FILE_CTRL, "ROM File"},
{STR_FPU_CTRL, "FPU Emulation"},
{STR_WINDOW_TITLE, "Basilisk II"},
{STR_WINDOW_TITLE_FROZEN, "Basilisk II *** FROZEN ***"},