static void write_prefs(FILE *f, const prefs_desc *list) { while (list->type != TYPE_ANY) { switch (list->type) { case TYPE_STRING: { int index = 0; const char *str; while ((str = PrefsFindString(list->name, index++)) != NULL) fprintf(f, "%s %s\n", list->name, str); break; } case TYPE_BOOLEAN: fprintf(f, "%s %s\n", list->name, PrefsFindBool(list->name) ? "true" : "false"); break; case TYPE_INT16: fprintf(f, "%s %d\n", list->name, PrefsFindInt16(list->name)); break; case TYPE_INT32: fprintf(f, "%s %ld\n", list->name, PrefsFindInt32(list->name)); break; default: break; } list++; } }
BView *PrefsWindow::create_serial_pane(void) { BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_SERIAL_NETWORK_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW); pane->SetViewColor(fill_color); float right = pane->Bounds().right-10; BMenuField *menu_field; BPopUpMenu *menu_a = new BPopUpMenu(""); add_serial_names(menu_a, MSG_SER_A); menu_field = new BMenuField(BRect(10, 5, right, 20), "seriala", GetString(STR_SERIALA_CTRL), menu_a); menu_field->SetDivider(90); pane->AddChild(menu_field); set_serial_label(menu_a, "seriala"); BPopUpMenu *menu_b = new BPopUpMenu(""); add_serial_names(menu_b, MSG_SER_B); menu_field = new BMenuField(BRect(10, 26, right, 41), "serialb", GetString(STR_SERIALB_CTRL), menu_b); menu_field->SetDivider(90); pane->AddChild(menu_field); set_serial_label(menu_b, "serialb"); ether_checkbox = new BCheckBox(BRect(10, 47, right, 62), "ether", GetString(STR_ETHER_ENABLE_CTRL), new BMessage(MSG_ETHER)); pane->AddChild(ether_checkbox); ether_checkbox->SetValue(PrefsFindString("ether") ? B_CONTROL_ON : B_CONTROL_OFF); udptunnel_checkbox = new BCheckBox(BRect(10, 67, right, 72), "udptunnel", GetString(STR_UDPTUNNEL_CTRL), new BMessage(MSG_UDPTUNNEL)); pane->AddChild(udptunnel_checkbox); udptunnel_checkbox->SetValue(PrefsFindBool("udptunnel") ? B_CONTROL_ON : B_CONTROL_OFF); udpport_ctrl = new NumberControl(BRect(10, 87, right / 2, 105), 118, "udpport", GetString(STR_UDPPORT_CTRL), PrefsFindInt32("udpport"), NULL); pane->AddChild(udpport_ctrl); hide_show_serial_ctrls(); return pane; }
static void set_serial_label(BPopUpMenu *menu, const char *prefs_name) { const char *str; BMenuItem *item; if ((str = PrefsFindString(prefs_name)) != NULL) if ((item = menu->FindItem(str)) != NULL) item->SetMarked(true); }
BView *PrefsWindow::create_volumes_pane(void) { BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_VOLUMES_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW); pane->SetViewColor(fill_color); float right = pane->Bounds().right-10; const char *str; int32 index = 0; volume_list = new VolumeListView(BRect(15, 10, pane->Bounds().right-30, 113), "volumes"); while ((str = PrefsFindString("disk", index++)) != NULL) volume_list->AddItem(new BStringItem(str)); volume_list->SetSelectionMessage(new BMessage(MSG_VOLUME_SELECTED)); volume_list->SetInvocationMessage(new BMessage(MSG_VOLUME_INVOKED)); pane->AddChild(new BScrollView("volumes_border", volume_list, B_FOLLOW_LEFT | B_FOLLOW_TOP, 0, false, true)); pane->AddChild(new BButton(BRect(10, 118, pane->Bounds().right/3, 138), "add_volume", GetString(STR_ADD_VOLUME_BUTTON), new BMessage(MSG_ADD_VOLUME))); pane->AddChild(new BButton(BRect(pane->Bounds().right/3, 118, pane->Bounds().right*2/3, 138), "create_volume", GetString(STR_CREATE_VOLUME_BUTTON), new BMessage(MSG_CREATE_VOLUME))); pane->AddChild(new BButton(BRect(pane->Bounds().right*2/3, 118, pane->Bounds().right-11, 138), "remove_volume", GetString(STR_REMOVE_VOLUME_BUTTON), new BMessage(MSG_REMOVE_VOLUME))); extfs_control = new PathControl(true, BRect(10, 145, right, 160), "extfs", GetString(STR_EXTFS_CTRL), PrefsFindString("extfs"), NULL); extfs_control->SetDivider(90); pane->AddChild(extfs_control); BMenuField *menu_field; BPopUpMenu *menu = new BPopUpMenu(""); menu_field = new BMenuField(BRect(10, 165, right, 180), "bootdriver", GetString(STR_BOOTDRIVER_CTRL), menu); menu_field->SetDivider(90); menu->AddItem(new BMenuItem(GetString(STR_BOOT_ANY_LAB), new BMessage(MSG_BOOT_ANY))); menu->AddItem(new BMenuItem(GetString(STR_BOOT_CDROM_LAB), new BMessage(MSG_BOOT_CDROM))); pane->AddChild(menu_field); int32 i32 = PrefsFindInt32("bootdriver"); BMenuItem *item; if (i32 == 0) { if ((item = menu->FindItem(GetString(STR_BOOT_ANY_LAB))) != NULL) item->SetMarked(true); } else if (i32 == CDROMRefNum) { if ((item = menu->FindItem(GetString(STR_BOOT_CDROM_LAB))) != NULL) item->SetMarked(true); } nocdrom_checkbox = new BCheckBox(BRect(10, 185, right, 200), "nocdrom", GetString(STR_NOCDROM_CTRL), new BMessage(MSG_NOCDROM)); pane->AddChild(nocdrom_checkbox); nocdrom_checkbox->SetValue(PrefsFindBool("nocdrom") ? B_CONTROL_ON : B_CONTROL_OFF); return pane; }
bool ether_init(void) { // Do nothing if no Ethernet device specified if (PrefsFindString("ether") == NULL) return false; // Initialize protocol list NewList(&prot_list); // Create message port reply_port = CreateMsgPort(); if (reply_port == NULL) goto open_error; D(bug("signal mask %08lx\n", 1 << reply_port->mp_SigBit)); // Start process proc_error = false; SetSignal(0, SIGF_SINGLE); net_proc = CreateNewProcTags( NP_Entry, (ULONG)net_func, NP_Name, (ULONG)"Basilisk II Ethernet Task", NP_Priority, 1, TAG_END ); if (net_proc == NULL) goto open_error; // Wait for signal from process Wait(SIGF_SINGLE); // Initialization error? Then bail out if (proc_error) goto open_error; // Everything OK return true; open_error: net_proc = NULL; if (reply_port) { DeleteMsgPort(reply_port); reply_port = NULL; } return false; }
void SCSIInit(void) { int id; // Allocate buffer buffer = (uint8 *)malloc(buffer_size = 0x10000); // Open generic SCSI driver for all 8 units for (id=0; id<8; id++) { char prefs_name[16]; sprintf(prefs_name, "scsi%d", id); const char *str = PrefsFindString(prefs_name); if (str) { int fd = fds[id] = open(str, O_RDWR | O_EXCL); if (fd > 0) { // Is it really a Generic SCSI device? int timeout = ioctl(fd, SG_GET_TIMEOUT); if (timeout < 0) { // Error with SG_GET_TIMEOUT, doesn't seem to be a Generic SCSI device char msg[256]; sprintf(msg, GetString(STR_SCSI_DEVICE_NOT_SCSI_WARN), str); WarningAlert(msg); close(fd); fds[id] = -1; } else { // Flush unwanted garbage from previous use of device uint8 reply[256]; int old_fl = fcntl(fd, F_GETFL); fcntl(fd, F_SETFL, old_fl | O_NONBLOCK); while (read(fd, reply, sizeof(reply)) != -1 || errno != EAGAIN) ; fcntl(fd, F_SETFL, old_fl); } } else { char msg[256]; sprintf(msg, GetString(STR_SCSI_DEVICE_OPEN_WARN), str, strerror(errno)); WarningAlert(msg); } } } // Reset SCSI bus SCSIReset(); }
static void init_tcp_listen_ports() { int32 index = 0; const char *port_str; while ((port_str = PrefsFindString("tcp_port", index++)) != NULL) { uint32 iface = 0; char *if_str = strchr(port_str,','); if(if_str) { *if_str++ = 0; uint32 if_net = _inet_addr( if_str ); if(if_net == INADDR_NONE) if_net = INADDR_ANY; iface = ntohl( if_net ); } uint16 port = (uint16)strtoul( port_str, 0, 0 ); if( port ) { uint32 ip = 0; bool once = false; alloc_listen_socket( port, ip, iface, once ); } } }
bool ether_init(void) { char str[256]; // Do nothing if no Ethernet device specified const char *name = PrefsFindString("ether"); if (name == NULL) return false; ether_multi_mode = PrefsFindInt32("ethermulticastmode"); ether_use_permanent = PrefsFindBool("etherpermanentaddress"); // Determine Ethernet device type net_if_type = -1; if (PrefsFindBool("routerenabled") || strcmp(name, "router") == 0) net_if_type = NET_IF_ROUTER; else if (strcmp(name, "slirp") == 0) net_if_type = NET_IF_SLIRP; else if (strcmp(name, "tap") == 0) net_if_type = NET_IF_TAP; else net_if_type = NET_IF_B2ETHER; // Initialize NAT-Router if (net_if_type == NET_IF_ROUTER) { if (!router_init()) net_if_type = NET_IF_FAKE; } // Initialize slirp library if (net_if_type == NET_IF_SLIRP) { if (slirp_init() < 0) { sprintf(str, GetString(STR_SLIRP_NO_DNS_FOUND_WARN)); WarningAlert(str); return false; } } // Open ethernet device const char *dev_name; switch (net_if_type) { case NET_IF_B2ETHER: dev_name = PrefsFindString("etherguid"); if (dev_name == NULL || strcmp(name, "b2ether") != 0) dev_name = name; break; case NET_IF_TAP: dev_name = PrefsFindString("etherguid"); break; } if (net_if_type == NET_IF_B2ETHER) { if (dev_name == NULL) { WarningAlert("No ethernet device GUID specified. Ethernet is not available."); goto open_error; } fd = PacketOpenAdapter( dev_name, ether_multi_mode ); if (!fd) { sprintf(str, "Could not open ethernet adapter %s.", dev_name); WarningAlert(str); goto open_error; } // Get Ethernet address if(!PacketGetMAC(fd,ether_addr,ether_use_permanent)) { sprintf(str, "Could not get hardware address of device %s. Ethernet is not available.", dev_name); WarningAlert(str); goto open_error; } D(bug("Real ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); const char *ether_fake_address; ether_fake_address = PrefsFindString("etherfakeaddress"); if(ether_fake_address && strlen(ether_fake_address) == 12) { char sm[10]; strcpy( sm, "0x00" ); for( int i=0; i<6; i++ ) { sm[2] = ether_fake_address[i*2]; sm[3] = ether_fake_address[i*2+1]; ether_addr[i] = (uint8)strtoul(sm,0,0); } D(bug("Fake ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); } } else if (net_if_type == NET_IF_TAP) { if (dev_name == NULL) { WarningAlert("No ethernet device GUID specified. Ethernet is not available."); goto open_error; } fd = tap_open_adapter(dev_name); if (!fd) { sprintf(str, "Could not open ethernet adapter %s.", dev_name); WarningAlert(str); goto open_error; } if (!tap_check_version(fd)) { sprintf(str, "Minimal TAP-Win32 version supported is %d.%d.", TAP_VERSION_MIN_MAJOR, TAP_VERSION_MIN_MINOR); WarningAlert(str); goto open_error; } if (!tap_set_status(fd, true)) { sprintf(str, "Could not set media status to connected."); WarningAlert(str); goto open_error; } if (!tap_get_mac(fd, ether_addr)) { sprintf(str, "Could not get hardware address of device %s. Ethernet is not available.", dev_name); WarningAlert(str); goto open_error; } D(bug("Real ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); const char *ether_fake_address; ether_fake_address = PrefsFindString("etherfakeaddress"); if (ether_fake_address && strlen(ether_fake_address) == 12) { char sm[10]; strcpy( sm, "0x00" ); for( int i=0; i<6; i++ ) { sm[2] = ether_fake_address[i*2]; sm[3] = ether_fake_address[i*2+1]; ether_addr[i] = (uint8)strtoul(sm,0,0); } } #if 1 /* If we bridge the underlying ethernet connection and the TAP device altogether, we have to use a fake address. */ else { ether_addr[0] = 0x52; ether_addr[1] = 0x54; ether_addr[2] = 0x00; } #endif D(bug("Fake ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); } else if (net_if_type == NET_IF_SLIRP) { ether_addr[0] = 0x52; ether_addr[1] = 0x54; ether_addr[2] = 0x00; ether_addr[3] = 0x12; ether_addr[4] = 0x34; ether_addr[5] = 0x56; D(bug("Ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); } else { memcpy( ether_addr, router_mac_addr, 6 ); D(bug("Fake ethernet address (same as router) %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5])); } // Start packet reception thread int_ack = CreateSemaphore( 0, 0, 1, NULL); if(!int_ack) { WarningAlert("WARNING: Cannot create int_ack semaphore"); goto open_error; } // nonsignaled int_sig = CreateSemaphore( 0, 0, 1, NULL); if(!int_sig) { WarningAlert("WARNING: Cannot create int_sig semaphore"); goto open_error; } int_sig2 = CreateSemaphore( 0, 0, 1, NULL); if(!int_sig2) { WarningAlert("WARNING: Cannot create int_sig2 semaphore"); goto open_error; } int_send_now = CreateSemaphore( 0, 0, 1, NULL); if(!int_send_now) { WarningAlert("WARNING: Cannot create int_send_now semaphore"); goto open_error; } init_queue(); if(!allocate_read_packets()) goto open_error; // No need to enter wait state if we can avoid it. // These all terminate fast. if(pfnInitializeCriticalSectionAndSpinCount) { pfnInitializeCriticalSectionAndSpinCount( &fetch_csection, 5000 ); } else { InitializeCriticalSection( &fetch_csection ); } if(pfnInitializeCriticalSectionAndSpinCount) { pfnInitializeCriticalSectionAndSpinCount( &queue_csection, 5000 ); } else { InitializeCriticalSection( &queue_csection ); } if(pfnInitializeCriticalSectionAndSpinCount) { pfnInitializeCriticalSectionAndSpinCount( &send_csection, 5000 ); } else { InitializeCriticalSection( &send_csection ); } if(pfnInitializeCriticalSectionAndSpinCount) { pfnInitializeCriticalSectionAndSpinCount( &wpool_csection, 5000 ); } else { InitializeCriticalSection( &wpool_csection ); } ether_th = (HANDLE)_beginthreadex( 0, 0, ether_thread_feed_int, 0, 0, ðer_tid ); if (!ether_th) { D(bug("Failed to create ethernet thread\n")); goto open_error; } thread_active = true; unsigned int dummy; unsigned int (WINAPI *receive_func)(void *); switch (net_if_type) { case NET_IF_SLIRP: receive_func = slirp_receive_func; break; default: receive_func = ether_thread_get_packets_nt; break; } ether_th2 = (HANDLE)_beginthreadex( 0, 0, receive_func, 0, 0, &dummy ); ether_th1 = (HANDLE)_beginthreadex( 0, 0, ether_thread_write_packets, 0, 0, &dummy ); // Everything OK return true; open_error: if (thread_active) { TerminateThread(ether_th,0); ether_th = 0; if (int_ack) CloseHandle(int_ack); int_ack = 0; if(int_sig) CloseHandle(int_sig); int_sig = 0; if(int_sig2) CloseHandle(int_sig2); int_sig2 = 0; if(int_send_now) CloseHandle(int_send_now); int_send_now = 0; thread_active = false; } if (fd) { switch (net_if_type) { case NET_IF_B2ETHER: PacketCloseAdapter(fd); break; case NET_IF_TAP: tap_close_adapter(fd); break; } fd = 0; } return false; }
static __saveds void net_func(void) { const char *str; BYTE od_error; struct MsgPort *write_port = NULL, *control_port = NULL; struct IOSana2Req *write_io = NULL, *control_io = NULL; bool opened = false; ULONG read_mask = 0, write_mask = 0, proc_port_mask = 0; struct Sana2DeviceQuery query_data = {sizeof(Sana2DeviceQuery)}; ULONG buffer_tags[] = { S2_CopyToBuff, (uint32)copy_to_buff, S2_CopyFromBuff, (uint32)copy_from_buff, TAG_END }; // Default: error occured proc_error = true; // Create message port for communication with main task proc_port = CreateMsgPort(); if (proc_port == NULL) goto quit; proc_port_mask = 1 << proc_port->mp_SigBit; // Create message ports for device I/O read_port = CreateMsgPort(); if (read_port == NULL) goto quit; read_mask = 1 << read_port->mp_SigBit; write_port = CreateMsgPort(); if (write_port == NULL) goto quit; write_mask = 1 << write_port->mp_SigBit; control_port = CreateMsgPort(); if (control_port == NULL) goto quit; // Create control IORequest control_io = (struct IOSana2Req *)CreateIORequest(control_port, sizeof(struct IOSana2Req)); if (control_io == NULL) goto quit; control_io->ios2_Req.io_Message.mn_Node.ln_Type = 0; // Avoid CheckIO() bug // Parse device name char dev_name[256]; ULONG dev_unit; str = PrefsFindString("ether"); if (str) { const char *FirstSlash = strchr(str, '/'); const char *LastSlash = strrchr(str, '/'); if (FirstSlash && FirstSlash && FirstSlash != LastSlash) { // Device name contains path, i.e. "Networks/xyzzy.device" const char *lp = str; char *dp = dev_name; while (lp != LastSlash) *dp++ = *lp++; *dp = '\0'; if (strlen(dev_name) < 1) goto quit; if (sscanf(LastSlash, "/%ld", &dev_unit) != 1) goto quit; } else { if (sscanf(str, "%[^/]/%ld", dev_name, &dev_unit) != 2) goto quit; } } else goto quit; // Open device control_io->ios2_BufferManagement = buffer_tags; od_error = OpenDevice((UBYTE *) dev_name, dev_unit, (struct IORequest *)control_io, 0); if (od_error != 0 || control_io->ios2_Req.io_Device == 0) { printf("WARNING: OpenDevice(<%s>, unit=%d) returned error %d)\n", (UBYTE *)dev_name, dev_unit, od_error); goto quit; } opened = true; // Is it Ethernet? control_io->ios2_Req.io_Command = S2_DEVICEQUERY; control_io->ios2_StatData = (void *)&query_data; DoIO((struct IORequest *)control_io); if (control_io->ios2_Req.io_Error) goto quit; if (query_data.HardwareType != S2WireType_Ethernet) { WarningAlert(GetString(STR_NOT_ETHERNET_WARN)); goto quit; } // Yes, create IORequest for writing write_io = (struct IOSana2Req *)CreateIORequest(write_port, sizeof(struct IOSana2Req)); if (write_io == NULL) goto quit; memcpy(write_io, control_io, sizeof(struct IOSana2Req)); write_io->ios2_Req.io_Message.mn_Node.ln_Type = 0; // Avoid CheckIO() bug write_io->ios2_Req.io_Message.mn_ReplyPort = write_port; // Configure Ethernet control_io->ios2_Req.io_Command = S2_GETSTATIONADDRESS; DoIO((struct IORequest *)control_io); memcpy(ether_addr, control_io->ios2_DstAddr, 6); memcpy(control_io->ios2_SrcAddr, control_io->ios2_DstAddr, 6); control_io->ios2_Req.io_Command = S2_CONFIGINTERFACE; DoIO((struct IORequest *)control_io); D(bug("Ethernet address %08lx %08lx\n", *(uint32 *)ether_addr, *(uint16 *)(ether_addr + 4))); // Initialization went well, inform main task proc_error = false; Signal(MainTask, SIGF_SINGLE); // Main loop for (;;) { // Wait for I/O and messages (CTRL_C is used for quitting the task) ULONG sig = Wait(proc_port_mask | read_mask | write_mask | SIGBREAKF_CTRL_C); // Main task wants to quit us if (sig & SIGBREAKF_CTRL_C) break; // Main task sent a command to us if (sig & proc_port_mask) { struct NetMessage *msg; while (msg = (NetMessage *)GetMsg(proc_port)) { D(bug("net_proc received %08lx\n", msg->what)); switch (msg->what) { case MSG_CLEANUP: remove_all_protocols(); break; case MSG_ADD_MULTI: control_io->ios2_Req.io_Command = S2_ADDMULTICASTADDRESS; Mac2Host_memcpy(control_io->ios2_SrcAddr, msg->pointer + eMultiAddr, 6); DoIO((struct IORequest *)control_io); if (control_io->ios2_Req.io_Error == S2ERR_NOT_SUPPORTED) { WarningAlert(GetString(STR_NO_MULTICAST_WARN)); msg->result = noErr; } else if (control_io->ios2_Req.io_Error) msg->result = eMultiErr; else msg->result = noErr; break; case MSG_DEL_MULTI: control_io->ios2_Req.io_Command = S2_DELMULTICASTADDRESS; Mac2Host_memcpy(control_io->ios2_SrcAddr, msg->pointer + eMultiAddr, 6); DoIO((struct IORequest *)control_io); if (control_io->ios2_Req.io_Error) msg->result = eMultiErr; else msg->result = noErr; break; case MSG_ATTACH_PH: { uint16 type = msg->type; uint32 handler = msg->pointer; // Protocol of that type already installed? NetProtocol *p = (NetProtocol *)prot_list.lh_Head, *next; while ((next = (NetProtocol *)p->ln_Succ) != NULL) { if (p->type == type) { msg->result = lapProtErr; goto reply; } p = next; } // Allocate NetProtocol, set type and handler p = (NetProtocol *)AllocMem(sizeof(NetProtocol), MEMF_PUBLIC); if (p == NULL) { msg->result = lapProtErr; goto reply; } p->type = type; p->handler = handler; // Set up and submit read requests for (int i=0; i<NUM_READ_REQUESTS; i++) { memcpy(p->read_io + i, control_io, sizeof(struct IOSana2Req)); p->read_io[i].ios2_Req.io_Message.mn_Node.ln_Name = (char *)p; // Hide pointer to NetProtocol in node name p->read_io[i].ios2_Req.io_Message.mn_Node.ln_Type = 0; // Avoid CheckIO() bug p->read_io[i].ios2_Req.io_Message.mn_ReplyPort = read_port; p->read_io[i].ios2_Req.io_Command = CMD_READ; p->read_io[i].ios2_PacketType = type; p->read_io[i].ios2_Data = p->read_buf[i]; p->read_io[i].ios2_Req.io_Flags = SANA2IOF_RAW; BeginIO((struct IORequest *)(p->read_io + i)); } // Add protocol to list AddTail(&prot_list, p); // Everything OK msg->result = noErr; break; } case MSG_DETACH_PH: { uint16 type = msg->type; msg->result = lapProtErr; NetProtocol *p = (NetProtocol *)prot_list.lh_Head, *next; while ((next = (NetProtocol *)p->ln_Succ) != NULL) { if (p->type == type) { remove_protocol(p); msg->result = noErr; break; } p = next; } break; } case MSG_WRITE: { // Get pointer to Write Data Structure uint32 wds = msg->pointer; write_io->ios2_Data = (void *)wds; // Calculate total packet length long len = 0; uint32 tmp = wds; for (;;) { int16 w = ReadMacInt16(tmp); if (w == 0) break; len += w; tmp += 6; } write_io->ios2_DataLength = len; // Get destination address uint32 hdr = ReadMacInt32(wds + 2); Mac2Host_memcpy(write_io->ios2_DstAddr, hdr, 6); // Get packet type uint32 type = ReadMacInt16(hdr + 12); if (type <= 1500) type = 0; // 802.3 packet write_io->ios2_PacketType = type; // Multicast/broadcard packet? if (write_io->ios2_DstAddr[0] & 1) { if (*(uint32 *)(write_io->ios2_DstAddr) == 0xffffffff && *(uint16 *)(write_io->ios2_DstAddr + 4) == 0xffff) write_io->ios2_Req.io_Command = S2_BROADCAST; else write_io->ios2_Req.io_Command = S2_MULTICAST; } else write_io->ios2_Req.io_Command = CMD_WRITE; // Send packet write_done = false; write_io->ios2_Req.io_Flags = SANA2IOF_RAW; BeginIO((IORequest *)write_io); break; } } reply: D(bug(" net_proc replying\n")); ReplyMsg(msg); } } // Packet received if (sig & read_mask) { D(bug(" packet received, triggering Ethernet interrupt\n")); SetInterruptFlag(INTFLAG_ETHER); TriggerInterrupt(); } // Packet write completed if (sig & write_mask) { GetMsg(write_port); WriteMacInt32(ether_data + ed_Result, write_io->ios2_Req.io_Error ? excessCollsns : 0); write_done = true; D(bug(" packet write done, triggering Ethernet interrupt\n")); SetInterruptFlag(INTFLAG_ETHER); TriggerInterrupt(); } } quit: // Close everything remove_all_protocols(); if (opened) { if (CheckIO((struct IORequest *)write_io) == 0) { AbortIO((struct IORequest *)write_io); WaitIO((struct IORequest *)write_io); } CloseDevice((struct IORequest *)control_io); } if (write_io) DeleteIORequest(write_io); if (control_io) DeleteIORequest(control_io); if (control_port) DeleteMsgPort(control_port); if (write_port) DeleteMsgPort(write_port); if (read_port) DeleteMsgPort(read_port); // Send signal to main task to confirm termination Forbid(); Signal(MainTask, SIGF_SINGLE); }
void *Sys_open(const char *name, bool read_only) { bool is_file = strncmp(name, "/dev/", 5) != 0; #if defined(__FreeBSD__) // SCSI IDE bool is_cdrom = strncmp(name, "/dev/cd", 7) == 0 || strncmp(name, "/dev/acd", 8) == 0; #else bool is_cdrom = strncmp(name, "/dev/cd", 7) == 0; #endif bool is_floppy = strncmp(name, "/dev/fd", 7) == 0; bool is_polled_media = strncmp(name, "/dev/poll/", 10) == 0; if (is_floppy) // Floppy open fails if there's no disk inserted is_polled_media = true; #if defined __MACOSX__ // There is no set filename in /dev which is the cdrom, // so we have to see if it is any of the devices that we found earlier { int index = 0; const char *str; while ((str = PrefsFindString("cdrom", index++)) != NULL) { if (is_polled_media || strcmp(str, name) == 0) { is_cdrom = true; read_only = true; break; } } } #endif D(bug("Sys_open(%s, %s)\n", name, read_only ? "read-only" : "read/write")); // Check if write access is allowed, set read-only flag if not if (!read_only && access(name, W_OK)) read_only = true; // Print warning message and eventually unmount drive when this is an HFS volume mounted under Linux (double mounting will corrupt the volume) char mount_name[256]; if (!is_file && !read_only && is_drive_mounted(name, mount_name)) { char str[512]; sprintf(str, GetString(STR_VOLUME_IS_MOUNTED_WARN), mount_name); WarningAlert(str); sprintf(str, "umount %s", mount_name); if (system(str)) { sprintf(str, GetString(STR_CANNOT_UNMOUNT_WARN), mount_name, strerror(errno)); WarningAlert(str); return NULL; } } // Open file/device #if defined(BINCUE) void *binfd = open_bincue(name); if (binfd) { su_file_handle *fh = open_filehandle(name); D(bug("opening %s as bincue\n", name)); fh->bincue_fd = binfd; fh->is_bincue = true; fh->read_only = true; fh->is_media_present = true; sys_add_su_file_handle(fh); return fh; } #endif #if defined(HAVE_LIBVHD) int vhdsize; void *vhdfd = vhd_unix_open(name, &vhdsize, read_only); if (vhdfd) { su_file_handle *fh = open_filehandle(name); D(bug("opening %s as vnd\n", name)); fh->is_vhd = true; fh->vhd_fd = vhdfd; fh->read_only = read_only; fh->file_size = vhdsize; fh->is_media_present = true; sys_add_su_file_handle(fh); return fh; } #endif #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__MACOSX__) int fd = open(name, (read_only ? O_RDONLY : O_RDWR) | (is_cdrom ? O_NONBLOCK : 0)); #else int fd = open(name, read_only ? O_RDONLY : O_RDWR); #endif if (fd < 0 && !read_only) { // Read-write failed, try read-only read_only = true; fd = open(name, O_RDONLY); } if (fd >= 0 || is_polled_media) { su_file_handle *fh = open_filehandle(name); fh->fd = fd; fh->is_file = is_file; fh->read_only = read_only; fh->is_floppy = is_floppy; fh->is_cdrom = is_cdrom; if (fh->is_file) { fh->is_media_present = true; // Detect disk image file layout loff_t size = 0; size = lseek(fd, 0, SEEK_END); uint8 data[256]; lseek(fd, 0, SEEK_SET); read(fd, data, 256); FileDiskLayout(size, data, fh->start_byte, fh->file_size); } else { struct stat st; if (fstat(fd, &st) == 0) { fh->is_media_present = true; if (S_ISBLK(st.st_mode)) { fh->is_cdrom = is_cdrom; #if defined(__linux__) fh->is_floppy = (MAJOR(st.st_rdev) == FLOPPY_MAJOR); #ifdef CDROM_GET_CAPABILITY if (is_cdrom) { fh->cdrom_cap = ioctl(fh->fd, CDROM_GET_CAPABILITY); if (fh->cdrom_cap < 0) fh->cdrom_cap = 0; } #endif #elif defined(__FreeBSD__) fh->is_floppy = ((st.st_rdev >> 16) == 2); #ifdef CDIOCCAPABILITY if (is_cdrom) { if (ioctl(fh->fd, CDIOCCAPABILITY, &fh->cdrom_cap) < 0) memset(&fh->cdrom_cap, 0, sizeof(fh->cdrom_cap)); } #endif #elif defined(__NetBSD__) fh->is_floppy = ((st.st_rdev >> 16) == 2); #endif } #if defined __MACOSX__ if (is_cdrom) { fh->is_cdrom = true; fh->is_floppy = false; if (cdrom_open_1(fh)) fh->is_media_present = true; } #endif }
void SCSIInit(void) { int id, lun; int memtype = PrefsFindInt32("scsimemtype"); switch (memtype) { case 1: buffer_memf = MEMF_24BITDMA | MEMF_PUBLIC; break; case 2: buffer_memf = MEMF_ANY | MEMF_PUBLIC; direct_transfers_supported = true; break; default: buffer_memf = MEMF_CHIP | MEMF_PUBLIC; break; } // Create port and buffers the_port = CreateMsgPort(); buffer = (UBYTE *)AllocMem(buffer_size = 0x10000, buffer_memf); sense_buffer = (UBYTE *)AllocMem(SENSE_LENGTH, MEMF_CHIP | MEMF_PUBLIC); if (the_port == NULL || buffer == NULL || sense_buffer == NULL) { ErrorAlert(STR_NO_MEM_ERR); QuitEmulator(); } // Create and open IORequests for all 8 units (and all 8 LUNs) for (id=0; id<8; id++) { for (lun=0; lun<8; lun++) ios[id*8+lun] = NULL; char prefs_name[16]; sprintf(prefs_name, "scsi%d", id); const char *str = PrefsFindString(prefs_name); if (str) { char dev_name[256]; ULONG dev_unit = 0; if (sscanf(str, "%[^/]/%ld", dev_name, &dev_unit) == 2) { for (lun=0; lun<8; lun++) { struct IOStdReq *io = (struct IOStdReq *)CreateIORequest(the_port, sizeof(struct IOStdReq)); if (io == NULL) continue; if (OpenDevice((UBYTE *) dev_name, dev_unit + lun * 10, (struct IORequest *)io, 0)) { DeleteIORequest(io); continue; } io->io_Data = &scsi; io->io_Length = sizeof(scsi); io->io_Command = HD_SCSICMD; ios[id*8+lun] = io; } } } } // Reset SCSI bus SCSIReset(); // Init SCSICmd memset(&scsi, 0, sizeof(scsi)); scsi.scsi_Command = cmd_buffer; scsi.scsi_SenseData = sense_buffer; scsi.scsi_SenseLength = SENSE_LENGTH; }
void PrefsWindow::MessageReceived(BMessage *msg) { switch (msg->what) { case MSG_OK: { // "Start" button clicked read_volumes_prefs(); read_memory_prefs(); read_graphics_prefs(); SavePrefs(); send_quit_on_close = false; PostMessage(B_QUIT_REQUESTED); be_app->PostMessage(ok_message); break; } case MSG_CANCEL: // "Quit" button clicked send_quit_on_close = false; PostMessage(B_QUIT_REQUESTED); be_app->PostMessage(B_QUIT_REQUESTED); break; case B_ABOUT_REQUESTED: { // "About" menu item selected ShowAboutWindow(); break; } case MSG_ZAP_PRAM: // "Zap PRAM File" menu item selected ZapPRAM(); break; case MSG_VOLUME_INVOKED: { // Double-clicked on volume name, toggle read-only flag int selected = volume_list->CurrentSelection(); if (selected >= 0) { const char *str = PrefsFindString("disk", selected); BStringItem *item = (BStringItem *)volume_list->RemoveItem(selected); delete item; char newstr[256]; if (str[0] == '*') strcpy(newstr, str+1); else { strcpy(newstr, "*"); strcat(newstr, str); } PrefsReplaceString("disk", newstr, selected); volume_list->AddItem(new BStringItem(newstr), selected); volume_list->Select(selected); } break; } case MSG_ADD_VOLUME: add_volume_panel->Show(); break; case MSG_CREATE_VOLUME: create_volume_panel->Show(); break; case MSG_ADD_VOLUME_PANEL: { entry_ref ref; if (msg->FindRef("refs", &ref) == B_NO_ERROR) { BEntry entry(&ref, true); BPath path; entry.GetPath(&path); if (entry.IsFile()) { PrefsAddString("disk", path.Path()); volume_list->AddItem(new BStringItem(path.Path())); } else if (entry.IsDirectory()) { BVolume volume; if (path.Path()[0] == '/' && strchr(path.Path()+1, '/') == NULL && entry.GetVolume(&volume) == B_NO_ERROR) { int32 i = 0; dev_t d; fs_info info; while ((d = next_dev(&i)) >= 0) { fs_stat_dev(d, &info); if (volume.Device() == info.dev) { PrefsAddString("disk", info.device_name); volume_list->AddItem(new BStringItem(info.device_name)); } } } } } break; } case MSG_CREATE_VOLUME_PANEL: { entry_ref dir; if (msg->FindRef("directory", &dir) == B_NO_ERROR) { BEntry entry(&dir, true); BPath path; entry.GetPath(&path); path.Append(msg->FindString("name")); create_volume_panel->Window()->Lock(); BView *background = create_volume_panel->Window()->ChildAt(0); NumberControl *v = (NumberControl *)background->FindView("hardfile_size"); int size = v->Value(); char cmd[1024]; sprintf(cmd, "dd if=/dev/zero \"of=%s\" bs=1024k count=%d", path.Path(), size); int ret = system(cmd); if (ret == 0) { PrefsAddString("disk", path.Path()); volume_list->AddItem(new BStringItem(path.Path())); } else { sprintf(cmd, GetString(STR_CREATE_VOLUME_WARN), strerror(ret)); WarningAlert(cmd); } } break; } case MSG_REMOVE_VOLUME: { int selected = volume_list->CurrentSelection(); if (selected >= 0) { PrefsRemoveItem("disk", selected); BStringItem *item = (BStringItem *)volume_list->RemoveItem(selected); delete item; volume_list->Select(selected); } break; } case MSG_BOOT_ANY: PrefsReplaceInt32("bootdriver", 0); break; case MSG_BOOT_CDROM: PrefsReplaceInt32("bootdriver", CDROMRefNum); break; case MSG_NOCDROM: PrefsReplaceBool("nocdrom", nocdrom_checkbox->Value() == B_CONTROL_ON); break; case MSG_VIDEO_WINDOW: display_type = DISPLAY_WINDOW; hide_show_graphics_ctrls(); break; case MSG_VIDEO_SCREEN: display_type = DISPLAY_SCREEN; hide_show_graphics_ctrls(); break; case MSG_REF_5HZ: PrefsReplaceInt32("frameskip", 12); break; case MSG_REF_7_5HZ: PrefsReplaceInt32("frameskip", 8); break; case MSG_REF_10HZ: PrefsReplaceInt32("frameskip", 6); break; case MSG_REF_15HZ: PrefsReplaceInt32("frameskip", 4); break; case MSG_REF_30HZ: PrefsReplaceInt32("frameskip", 2); break; case MSG_NOSOUND: PrefsReplaceBool("nosound", nosound_checkbox->Value() == B_CONTROL_ON); break; case MSG_SER_A: { BMenuItem *source = NULL; msg->FindPointer("source", (void **)&source); if (source) PrefsReplaceString("seriala", source->Label()); break; } case MSG_SER_B: { BMenuItem *source = NULL; msg->FindPointer("source", (void **)&source); if (source) PrefsReplaceString("serialb", source->Label()); break; } case MSG_ETHER: if (ether_checkbox->Value() == B_CONTROL_ON) PrefsReplaceString("ether", "yes"); else PrefsRemoveItem("ether"); break; case MSG_UDPTUNNEL: PrefsReplaceBool("udptunnel", udptunnel_checkbox->Value() == B_CONTROL_ON); hide_show_serial_ctrls(); break; case MSG_RAMSIZE: PrefsReplaceInt32("ramsize", ramsize_slider->Value() * 1024 * 1024); break; case MSG_MODELID_5: PrefsReplaceInt32("modelid", 5); break; case MSG_MODELID_14: PrefsReplaceInt32("modelid", 14); break; case MSG_CPU_68020: PrefsReplaceInt32("cpu", 2); PrefsReplaceBool("fpu", false); break; case MSG_CPU_68020_FPU: PrefsReplaceInt32("cpu", 2); PrefsReplaceBool("fpu", true); break; case MSG_CPU_68030: PrefsReplaceInt32("cpu", 3); PrefsReplaceBool("fpu", false); break; case MSG_CPU_68030_FPU: PrefsReplaceInt32("cpu", 3); PrefsReplaceBool("fpu", true); break; case MSG_CPU_68040: PrefsReplaceInt32("cpu", 4); PrefsReplaceBool("fpu", true); break; default: { // Screen mode messages if ((msg->what & 0xffff0000) == MSG_SCREEN_MODE) { int m = msg->what & 0xffff; uint32 mask = scr_mode[m].mode_mask; for (int i=0; i<32; i++) if (mask & (1 << i)) scr_mode_bit = i; } else BWindow::MessageReceived(msg); } } }
BView *PrefsWindow::create_memory_pane(void) { char str[256], str2[256]; BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_MEMORY_MISC_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW); pane->SetViewColor(fill_color); float right = pane->Bounds().right-10; BEntry entry("/boot/var/swap"); off_t swap_space; if (entry.GetSize(&swap_space) == B_NO_ERROR) max_ramsize = swap_space / (1024 * 1024) - 8; else max_ramsize = sys_info.max_pages * B_PAGE_SIZE / (1024 * 1024) - 8; int32 value = PrefsFindInt32("ramsize") / (1024 * 1024); ramsize_slider = new RAMSlider(BRect(10, 5, right, 55), "ramsize", GetString(STR_RAMSIZE_SLIDER), new BMessage(MSG_RAMSIZE), 1, max_ramsize, B_TRIANGLE_THUMB); ramsize_slider->SetValue(value); ramsize_slider->UseFillColor(true, &slider_fill_color); sprintf(str, GetString(STR_RAMSIZE_FMT), 1); sprintf(str2, GetString(STR_RAMSIZE_FMT), max_ramsize); ramsize_slider->SetLimitLabels(str, str2); pane->AddChild(ramsize_slider); BMenuField *menu_field; BMenuItem *item; BPopUpMenu *menu; int id = PrefsFindInt32("modelid"); menu = new BPopUpMenu(""); menu_field = new BMenuField(BRect(10, 60, right, 75), "modelid", GetString(STR_MODELID_CTRL), menu); menu_field->SetDivider(120); menu->AddItem(item = new BMenuItem(GetString(STR_MODELID_5_LAB), new BMessage(MSG_MODELID_5))); if (id == 5) item->SetMarked(true); menu->AddItem(item = new BMenuItem(GetString(STR_MODELID_14_LAB), new BMessage(MSG_MODELID_14))); if (id == 14) item->SetMarked(true); pane->AddChild(menu_field); int cpu = PrefsFindInt32("cpu"); bool fpu = PrefsFindBool("fpu"); menu = new BPopUpMenu(""); menu_field = new BMenuField(BRect(10, 82, right, 97), "cpu", GetString(STR_CPU_CTRL), menu); menu_field->SetDivider(120); menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68020_LAB), new BMessage(MSG_CPU_68020))); if (cpu == 2 && !fpu) item->SetMarked(true); menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68020_FPU_LAB), new BMessage(MSG_CPU_68020_FPU))); if (cpu == 2 && fpu) item->SetMarked(true); menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68030_LAB), new BMessage(MSG_CPU_68030))); if (cpu == 3 && !fpu) item->SetMarked(true); menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68030_FPU_LAB), new BMessage(MSG_CPU_68030_FPU))); if (cpu == 3 && fpu) item->SetMarked(true); menu->AddItem(item = new BMenuItem(GetString(STR_CPU_68040_LAB), new BMessage(MSG_CPU_68040))); if (cpu == 4) item->SetMarked(true); pane->AddChild(menu_field); rom_control = new PathControl(false, BRect(10, 104, right, 119), "rom", GetString(STR_ROM_FILE_CTRL), PrefsFindString("rom"), NULL); rom_control->SetDivider(117); pane->AddChild(rom_control); return pane; }
BView *PrefsWindow::create_graphics_pane(void) { BView *pane = new BView(BRect(0, 0, top_frame.right-20, top_frame.bottom-80), GetString(STR_GRAPHICS_SOUND_PANE_TITLE), B_FOLLOW_NONE, B_WILL_DRAW); pane->SetViewColor(fill_color); float right = pane->Bounds().right-10; const char *mode_str = PrefsFindString("screen"); int width = 512, height = 384; scr_mode_bit = 0; display_type = DISPLAY_WINDOW; if (mode_str) { if (sscanf(mode_str, "win/%d/%d", &width, &height) == 2) display_type = DISPLAY_WINDOW; else if (sscanf(mode_str, "scr/%d", &scr_mode_bit) == 1) display_type = DISPLAY_SCREEN; } BMenuField *menu_field; BMenuItem *item; BPopUpMenu *menu; menu = new BPopUpMenu(""); menu_field = new BMenuField(BRect(10, 5, right, 20), "videotype", GetString(STR_VIDEO_TYPE_CTRL), menu); menu_field->SetDivider(120); menu->AddItem(item = new BMenuItem(GetString(STR_WINDOW_LAB), new BMessage(MSG_VIDEO_WINDOW))); if (display_type == DISPLAY_WINDOW) item->SetMarked(true); menu->AddItem(item = new BMenuItem(GetString(STR_FULLSCREEN_LAB), new BMessage(MSG_VIDEO_SCREEN))); if (display_type == DISPLAY_SCREEN) item->SetMarked(true); pane->AddChild(menu_field); menu = new BPopUpMenu(""); frameskip_menu = new BMenuField(BRect(10, 26, right, 41), "frameskip", GetString(STR_FRAMESKIP_CTRL), menu); frameskip_menu->SetDivider(120); menu->AddItem(new BMenuItem(GetString(STR_REF_5HZ_LAB), new BMessage(MSG_REF_5HZ))); menu->AddItem(new BMenuItem(GetString(STR_REF_7_5HZ_LAB), new BMessage(MSG_REF_7_5HZ))); menu->AddItem(new BMenuItem(GetString(STR_REF_10HZ_LAB), new BMessage(MSG_REF_10HZ))); menu->AddItem(new BMenuItem(GetString(STR_REF_15HZ_LAB), new BMessage(MSG_REF_15HZ))); menu->AddItem(new BMenuItem(GetString(STR_REF_30HZ_LAB), new BMessage(MSG_REF_30HZ))); pane->AddChild(frameskip_menu); int32 i32 = PrefsFindInt32("frameskip"); if (i32 == 12) { if ((item = menu->FindItem(GetString(STR_REF_5HZ_LAB))) != NULL) item->SetMarked(true); } else if (i32 == 8) { if ((item = menu->FindItem(GetString(STR_REF_7_5HZ_LAB))) != NULL) item->SetMarked(true); } else if (i32 == 6) { if ((item = menu->FindItem(GetString(STR_REF_10HZ_LAB))) != NULL) item->SetMarked(true); } else if (i32 == 4) { if ((item = menu->FindItem(GetString(STR_REF_15HZ_LAB))) != NULL) item->SetMarked(true); } else if (i32 == 2) { if ((item = menu->FindItem(GetString(STR_REF_30HZ_LAB))) != NULL) item->SetMarked(true); } display_x_ctrl = new NumberControl(BRect(10, 48, right / 2, 66), 118, "width", GetString(STR_DISPLAY_X_CTRL), width, NULL); pane->AddChild(display_x_ctrl); display_y_ctrl = new NumberControl(BRect(10, 69, right / 2, 87), 118, "height", GetString(STR_DISPLAY_Y_CTRL), height, NULL); pane->AddChild(display_y_ctrl); menu = new BPopUpMenu(""); scr_mode_menu = new BMenuField(BRect(10, 26, right, 41), "screenmode", GetString(STR_SCREEN_MODE_CTRL), menu); scr_mode_menu->SetDivider(120); for (int i=0; scr_mode[i].mode_mask; i++) { menu->AddItem(item = new BMenuItem(GetString(scr_mode[i].str), new BMessage(MSG_SCREEN_MODE + i))); if (scr_mode[i].mode_mask & (1 << scr_mode_bit)) item->SetMarked(true); } pane->AddChild(scr_mode_menu); nosound_checkbox = new BCheckBox(BRect(10, 90, right, 105), "nosound", GetString(STR_NOSOUND_CTRL), new BMessage(MSG_NOSOUND)); pane->AddChild(nosound_checkbox); nosound_checkbox->SetValue(PrefsFindBool("nosound") ? B_CONTROL_ON : B_CONTROL_OFF); hide_show_graphics_ctrls(); return pane; }
int main(int argc, char **argv) { char str[256]; int16 i16; HANDLE rom_fh; const char *rom_path; uint32 rom_size; DWORD actual; uint8 *rom_tmp; // Initialize variables RAMBase = 0; // Print some info printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR); printf(" %s\n", GetString(STR_ABOUT_TEXT2)); // Read preferences PrefsInit(NULL, argc, argv); // Parse command line arguments for (int i=1; i<argc; i++) { if (strcmp(argv[i], "--help") == 0) { usage(argv[0]); } else if (argv[i][0] == '-') { fprintf(stderr, "Unrecognized option '%s'\n", argv[i]); usage(argv[0]); } } // Check we are using a Windows NT kernel >= 4.0 OSVERSIONINFO osvi; ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if (!GetVersionEx(&osvi)) { ErrorAlert("Could not determine OS type"); QuitEmulator(); } win_os = osvi.dwPlatformId; win_os_major = osvi.dwMajorVersion; if (win_os != VER_PLATFORM_WIN32_NT || win_os_major < 4) { ErrorAlert(GetString(STR_NO_WIN32_NT_4)); QuitEmulator(); } // Check that drivers are installed if (!check_drivers()) QuitEmulator(); // Load win32 libraries KernelInit(); // FIXME: default to DIB driver if (getenv("SDL_VIDEODRIVER") == NULL) putenv("SDL_VIDEODRIVER=windib"); // Initialize SDL system int sdl_flags = 0; #ifdef USE_SDL_VIDEO sdl_flags |= SDL_INIT_VIDEO; #endif #ifdef USE_SDL_AUDIO sdl_flags |= SDL_INIT_AUDIO; #endif assert(sdl_flags != 0); if (SDL_Init(sdl_flags) == -1) { char str[256]; sprintf(str, "Could not initialize SDL: %s.\n", SDL_GetError()); ErrorAlert(str); goto quit; } atexit(SDL_Quit); #ifdef ENABLE_MON // Initialize mon mon_init(); #endif // Install SIGSEGV handler for CPU emulator if (!sigsegv_install_handler(sigsegv_handler)) { sprintf(str, GetString(STR_SIGSEGV_INSTALL_ERR), strerror(errno)); ErrorAlert(str); goto quit; } // Initialize VM system vm_init(); // Get system info PVR = 0x00040000; // Default: 604 CPUClockSpeed = 100000000; // Default: 100MHz BusClockSpeed = 100000000; // Default: 100MHz TimebaseSpeed = 25000000; // Default: 25MHz PVR = 0x000c0000; // Default: 7400 (with AltiVec) D(bug("PVR: %08x (assumed)\n", PVR)); // Init system routines SysInit(); // Show preferences editor if (!PrefsFindBool("nogui")) if (!PrefsEditor()) goto quit; // Create areas for Kernel Data if (!kernel_data_init()) goto quit; kernel_data = (KernelData *)Mac2HostAddr(KERNEL_DATA_BASE); emulator_data = &kernel_data->ed; KernelDataAddr = KERNEL_DATA_BASE; D(bug("Kernel Data at %p (%08x)\n", kernel_data, KERNEL_DATA_BASE)); D(bug("Emulator Data at %p (%08x)\n", emulator_data, KERNEL_DATA_BASE + offsetof(KernelData, ed))); // Create area for DR Cache if (vm_mac_acquire(DR_EMULATOR_BASE, DR_EMULATOR_SIZE) < 0) { sprintf(str, GetString(STR_DR_EMULATOR_MMAP_ERR), strerror(errno)); ErrorAlert(str); goto quit; } dr_emulator_area_mapped = true; if (vm_mac_acquire(DR_CACHE_BASE, DR_CACHE_SIZE) < 0) { sprintf(str, GetString(STR_DR_CACHE_MMAP_ERR), strerror(errno)); ErrorAlert(str); goto quit; } dr_cache_area_mapped = true; DRCacheAddr = (uint32)Mac2HostAddr(DR_CACHE_BASE); D(bug("DR Cache at %p (%08x)\n", DRCacheAddr, DR_CACHE_BASE)); // Create area for SheepShaver data if (!SheepMem::Init()) { sprintf(str, GetString(STR_SHEEP_MEM_MMAP_ERR), strerror(errno)); ErrorAlert(str); goto quit; } // Create area for Mac ROM if (vm_mac_acquire(ROM_BASE, ROM_AREA_SIZE) < 0) { sprintf(str, GetString(STR_ROM_MMAP_ERR), strerror(errno)); ErrorAlert(str); goto quit; } ROMBase = ROM_BASE; ROMBaseHost = Mac2HostAddr(ROMBase); rom_area_mapped = true; D(bug("ROM area at %p (%08x)\n", ROMBaseHost, ROMBase)); // Create area for Mac RAM RAMSize = PrefsFindInt32("ramsize"); if (RAMSize < 8*1024*1024) { WarningAlert(GetString(STR_SMALL_RAM_WARN)); RAMSize = 8*1024*1024; } RAMBase = 0; if (vm_mac_acquire(RAMBase, RAMSize) < 0) { sprintf(str, GetString(STR_RAM_MMAP_ERR), strerror(errno)); ErrorAlert(str); goto quit; } RAMBaseHost = Mac2HostAddr(RAMBase); ram_area_mapped = true; D(bug("RAM area at %p (%08x)\n", RAMBaseHost, RAMBase)); if (RAMBase > ROMBase) { ErrorAlert(GetString(STR_RAM_HIGHER_THAN_ROM_ERR)); goto quit; } // Load Mac ROM rom_path = PrefsFindString("rom"); rom_fh = CreateFile(rom_path && *rom_path ? rom_path : ROM_FILE_NAME, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (rom_fh == INVALID_HANDLE_VALUE) { rom_fh = CreateFile(ROM_FILE_NAME2, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (rom_fh == INVALID_HANDLE_VALUE) { ErrorAlert(GetString(STR_NO_ROM_FILE_ERR)); goto quit; } } printf(GetString(STR_READING_ROM_FILE)); rom_size = GetFileSize(rom_fh, NULL); rom_tmp = new uint8[ROM_SIZE]; ReadFile(rom_fh, (void *)rom_tmp, ROM_SIZE, &actual, NULL); CloseHandle(rom_fh); // Decode Mac ROM if (!DecodeROM(rom_tmp, actual)) { if (rom_size != 4*1024*1024) { ErrorAlert(GetString(STR_ROM_SIZE_ERR)); goto quit; } else { ErrorAlert(GetString(STR_ROM_FILE_READ_ERR)); goto quit; } } delete[] rom_tmp; // Initialize native timers timer_init(); // Initialize everything if (!InitAll(NULL)) goto quit; D(bug("Initialization complete\n")); // Write protect ROM vm_protect(ROMBaseHost, ROM_AREA_SIZE, VM_PAGE_READ); // Start 60Hz thread tick_thread_cancel = false; tick_thread_active = ((tick_thread = create_thread(tick_func)) != NULL); SetThreadPriority(tick_thread, THREAD_PRIORITY_ABOVE_NORMAL); D(bug("Tick thread installed (%ld)\n", tick_thread)); // Start NVRAM watchdog thread memcpy(last_xpram, XPRAM, XPRAM_SIZE); nvram_thread_cancel = false; nvram_thread_active = ((nvram_thread = create_thread(nvram_func, NULL)) != NULL); SetThreadPriority(nvram_thread, THREAD_PRIORITY_BELOW_NORMAL); D(bug("NVRAM thread installed (%ld)\n", nvram_thread)); // Get my thread ID and jump to ROM boot routine emul_thread = GetCurrentThread(); D(bug("Jumping to ROM\n")); #ifdef _MSC_VER __try { #endif jump_to_rom(ROMBase + 0x310000); #ifdef _MSC_VER } __except (main_exception_filter(GetExceptionInformation())) {} #endif D(bug("Returned from ROM\n")); quit: Quit(); return 0; }
// !!UNC void init_posix_emu(void) { if(!validate_stat_struct) { ErrorAlert( "Invalid struct my_stat -- edit posix_emu.h" ); QuitEmulator(); } #if DEBUG_EXTFS debug_extfs = PrefsFindInt16("debugextfs"); debug_extfs = DB_EXTFS_LOUD; if(debug_extfs != DB_EXTFS_NONE) { extfs_log_open( EXTFS_LOG_FILE_NAME ); } #endif // We cannot use ExtFS "RootPath" because of the virtual desktop. if(PrefsFindBool("enableextfs")) { PrefsReplaceString("extfs", ""); } else { PrefsRemoveItem("extfs"); D(bug("extfs disabled by user\n")); #if DEBUG_EXTFS extfs_log_close(); #endif return; } const char *extdrives = PrefsFindString("extdrives"); // Set up drive list. size_t outinx = 0; for( TCHAR letter = TEXT('A'); letter <= TEXT('Z'); letter++ ) { if(extdrives && !strchr(extdrives,letter)) continue; TCHAR rootdir[20]; _sntprintf( rootdir, lengthof(rootdir), TEXT("%c:\\"), letter ); use_streams[ letter - 'A' ] = false; switch(GetDriveType(rootdir)) { case DRIVE_FIXED: case DRIVE_REMOTE: case DRIVE_RAMDISK: // TODO: NTFS AFP? // fall case DRIVE_REMOVABLE: case DRIVE_CDROM: if(outinx < lengthof(host_drive_list)) { host_drive_list[outinx] = letter; outinx += 2; } } } // Set up virtual desktop root. // TODO: this should be customizable. GetModuleFileName( NULL, virtual_root, lengthof(virtual_root) ); TCHAR *p = _tcsrchr( virtual_root, TEXT('\\') ); if(p) { _tcscpy( ++p, desktop_name ); } else { // should never happen _sntprintf( virtual_root, lengthof(virtual_root), TEXT("C:\\%s"), desktop_name ); } CreateDirectory( virtual_root, 0 ); // Set up an icon looking like "My Computer" // Can be overwritten just like any other folder custom icon. if(my_access(custom_icon_name,0) != 0) { int fd = my_creat( custom_icon_name, 0 ); if(fd >= 0) { my_close(fd); fd = open_rfork( custom_icon_name, O_RDWR|O_CREAT ); if(fd >= 0) { my_write( fd, my_comp_icon, sizeof(my_comp_icon) ); my_close(fd); static uint8 host_finfo[SIZEOF_FInfo]; uint32 finfo = Host2MacAddr(host_finfo); get_finfo(custom_icon_name, finfo, 0, false); WriteMacInt16(finfo + fdFlags, kIsInvisible); set_finfo(custom_icon_name, finfo, 0, false); get_finfo(my_computer, finfo, 0, true); WriteMacInt16(finfo + fdFlags, ReadMacInt16(finfo + fdFlags) | kHasCustomIcon); set_finfo(my_computer, finfo, 0, true); } else { my_remove(custom_icon_name); } } } }
void SerialInit(void) { // Read serial preferences and create structs for both ports the_serd_port[0] = new ASERDPort(PrefsFindString("seriala")); the_serd_port[1] = new ASERDPort(PrefsFindString("serialb")); }
bool VideoInit(bool classic) { classic_mode = classic; // Get screen mode from preferences const char *mode_str; if (classic_mode) mode_str = "win/512/342"; else mode_str = PrefsFindString("screen"); // Determine type and mode int default_width = 512, default_height = 384; display_type = DISPLAY_WINDOW; if (mode_str) { if (sscanf(mode_str, "win/%d/%d", &default_width, &default_height) == 2) display_type = DISPLAY_WINDOW; else if (sscanf(mode_str, "scr/%d", &scr_mode_bit) == 1) display_type = DISPLAY_SCREEN; } #if 0 if (default_width <= 0) default_width = DisplayWidth(x_display, screen); else if (default_width > DisplayWidth(x_display, screen)) default_width = DisplayWidth(x_display, screen); if (default_height <= 0) default_height = DisplayHeight(x_display, screen); else if (default_height > DisplayHeight(x_display, screen)) default_height = DisplayHeight(x_display, screen); #endif // Mac screen depth follows BeOS depth video_depth default_depth = VDEPTH_1BIT; switch (BScreen().ColorSpace()) { case B_CMAP8: default_depth = VDEPTH_8BIT; break; case B_RGB15: default_depth = VDEPTH_16BIT; break; case B_RGB32: default_depth = VDEPTH_32BIT; break; default: fprintf(stderr, "Unknown color space!"); } // Construct list of supported modes if (display_type == DISPLAY_WINDOW) { if (classic) add_mode(512, 342, 0x80, 64, VDEPTH_1BIT); else { add_mode(default_width, default_height, 0x80, TrivialBytesPerRow(default_width, default_depth), default_depth); #if 0 for (unsigned d=VDEPTH_1BIT; d<=VDEPTH_32BIT; d++) { if (find_visual_for_depth(video_depth(d))) add_window_modes(video_depth(d)); } #endif } } else add_mode(default_width, default_height, 0x80, TrivialBytesPerRow(default_width, default_depth), default_depth); if (VideoModes.empty()) { ErrorAlert(STR_VIDEO_FAILED); return false; } // Find requested default mode with specified dimensions uint32 default_id; std::vector<video_mode>::const_iterator i, end = VideoModes.end(); for (i = VideoModes.begin(); i != end; ++i) { if (i->x == default_width && i->y == default_height && i->depth == default_depth) { default_id = i->resolution_id; break; } } if (i == end) { // not found, use first available mode default_depth = VideoModes[0].depth; default_id = VideoModes[0].resolution_id; } #if DEBUG D(bug("Available video modes:\n")); for (i = VideoModes.begin(); i != end; ++i) { int bits = 1 << i->depth; if (bits == 16) bits = 15; else if (bits == 32) bits = 24; D(bug(" %dx%d (ID %02x), %d colors\n", i->x, i->y, i->resolution_id, 1 << bits)); } #endif // Create X11_monitor_desc for this (the only) display BeOS_monitor_desc *monitor = new BeOS_monitor_desc(VideoModes, default_depth, default_id); VideoMonitors.push_back(monitor); // Open display return monitor->video_open(); }