int dev_audio_f_BeginIO_2(emumsg_syscall_t *msg) { /* Make real syscall */ BeginIO((struct IORequest *)msg->arg[0]._aptr); return HOOK_DONE; }
void modifynoise(UWORD period, UWORD volume) { modifyreq->ioa_Period = period; modifyreq->ioa_Volume = volume; BeginIO(&(modifyreq->ioa_Request)); WaitIO(&(modifyreq->ioa_Request)); }
void start_noise(void) { nport = CreatePort(NULL,0); chipnoisedata = (UBYTE *)AllocMem(sizeof(noisedata), MEMF_CHIP); memcpy(chipnoisedata, noisedata, sizeof(noisedata)); audioreq = (struct IOAudio *)CreateExtIO(nport, sizeof(*audioreq)*2); modifyreq = audioreq+1; audioreq->ioa_Data = amap; audioreq->ioa_Length = sizeof(amap); OpenDevice(AUDIONAME, 0, &(audioreq->ioa_Request), 0); audioreq->ioa_Request.io_Command = CMD_WRITE; audioreq->ioa_Request.io_Message.mn_Length = sizeof(audioreq); audioreq->ioa_Data = chipnoisedata; audioreq->ioa_Length = sizeof(noisedata); audioreq->ioa_Period = PERIOD(440, sizeof(noisedata)); audioreq->ioa_Volume = 40; audioreq->ioa_Request.io_Flags = ADIOF_PERVOL; audioreq->ioa_Cycles = 0; /* Infinity */ memcpy(modifyreq, audioreq, sizeof(*audioreq)); modifyreq->ioa_Request.io_Command = ADCMD_PERVOL; BeginIO(&(audioreq->ioa_Request)); }
// // perform an I/O command and wait for completion // BYTE DoIO(struct IORequest *io) { if (!io || io->io_Device == NULL) return -1; io->io_Flags = IOF_QUICK; io->io_Message.Node.Type = 0; BeginIO(io); if (!io->io_Flags & IOF_QUICK) WaitIO(io); return io->io_Error; }
void EtherInterrupt(void) { D(bug("EtherIRQ\n")); // Packet write done, enqueue DT to call IODone if (write_done) { EnqueueMac(ether_data + ed_DeferredTask, 0xd92); write_done = false; } // Call protocol handler for received packets IOSana2Req *io; while (io = (struct IOSana2Req *)GetMsg(read_port)) { // Get pointer to NetProtocol (hidden in node name) NetProtocol *p = (NetProtocol *)io->ios2_Req.io_Message.mn_Node.ln_Name; // No default handler if (p->handler == 0) continue; // Copy header to RHA Host2Mac_memcpy(ether_data + ed_RHA, io->ios2_Data, 14); D(bug(" header %08lx%04lx %08lx%04lx %04lx\n", ReadMacInt32(ether_data + ed_RHA), ReadMacInt16(ether_data + ed_RHA + 4), ReadMacInt32(ether_data + ed_RHA + 6), ReadMacInt16(ether_data + ed_RHA + 10), ReadMacInt16(ether_data + ed_RHA + 12))); // Call protocol handler M68kRegisters r; r.d[0] = *(uint16 *)((uint32)io->ios2_Data + 12); // Packet type r.d[1] = io->ios2_DataLength - 18; // Remaining packet length (without header, for ReadPacket) (-18 because the CRC is also included) r.a[0] = (uint32)io->ios2_Data + 14; // Pointer to packet (host address, for ReadPacket) r.a[3] = ether_data + ed_RHA + 14; // Pointer behind header in RHA r.a[4] = ether_data + ed_ReadPacket; // Pointer to ReadPacket/ReadRest routines D(bug(" calling protocol handler %08lx, type %08lx, length %08lx, data %08lx, rha %08lx, read_packet %08lx\n", p->handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4])); Execute68k(p->handler, &r); // Resend IORequest io->ios2_Req.io_Flags = SANA2IOF_RAW; BeginIO((struct IORequest *)io); } D(bug(" EtherIRQ done\n")); }
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); }
int LIBFUNC L_Module_Entry( REG(a0, struct List *files), REG(a1, struct Screen *screen), REG(a2, IPCData *ipc), REG(a3, IPCData *main_ipc), REG(d0, ULONG mod_id), REG(d1, ULONG mod_data)) { struct IOAudio audio; struct MsgPort *reply_port; // Flash only? if (mod_id==FLASH) { DisplayBeep(screen); return 1; } // Create port if (!(reply_port=CreateMsgPort())) return 0; // Fill out audio request audio.ioa_Request.io_Message.mn_ReplyPort=reply_port; audio.ioa_Request.io_Message.mn_Node.ln_Pri=90; audio.ioa_Data=achannels; audio.ioa_Length=sizeof(achannels); // Open audio device if (!(OpenDevice("audio.device",0,(struct IORequest *)&audio,0))) { // Initialise write command audio.ioa_Request.io_Command=CMD_WRITE; audio.ioa_Request.io_Flags=ADIOF_PERVOL; audio.ioa_Volume=64; audio.ioa_Data=(UBYTE *)beepwave; // It's an alarm? if (mod_id==ALARM) { short a; // Waveform size audio.ioa_Length=8; // Standard length audio.ioa_Cycles=60; // Five cycles for (a=0;a<5;a++) { // High tone audio.ioa_Period=800; // Play sound BeginIO((struct IORequest *)&audio); WaitIO((struct IORequest *)&audio); // Low tone audio.ioa_Period=1200; // Play sound BeginIO((struct IORequest *)&audio); WaitIO((struct IORequest *)&audio); } } // Waveform size else audio.ioa_Length=sizeof(beepwave); // Set note information audio.ioa_Period=(mod_id==BEEP)?300:800; audio.ioa_Cycles=(mod_id==BEEP)?100:60; // Play sound BeginIO((struct IORequest *)&audio); WaitIO((struct IORequest *)&audio); // Close audio device CloseDevice((struct IORequest *)&audio); } // Delete message port DeleteMsgPort(reply_port); return 1; }
int main(int argc, char *argv[]) { struct MsgPort *AROSTCP_Port = NULL; wait_time = 0; if ((WFP_rda = ReadArgs(WaitForPort_ArgTemplate, WaitForPort_Arguments, NULL))) { if (WaitForPort_Arguments[0]) { D(bug("[WaitForPort] Waiting for '%s' port\n",WaitForPort_Arguments[0])); } timerport = CreateMsgPort(); if (timerport != NULL) { /* allocate and initialize the template message structure */ timerIORequest = (struct timerequest *) CreateIORequest(timerport, sizeof(struct timerequest)); if (timerIORequest != NULL) { if (!(OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)timerIORequest, 0))) { /* Make sure that we got at least V36 timer, since we use some * functions defined only in V36 and later. */ if ((timerIORequest->tr_node.io_Device)->dd_Library.lib_Version >= 36) { /* initialize TimerBase from timerIORequest */ TimerBase = timerIORequest->tr_node.io_Device; /* Initialize some fields of the IO request to common values */ timerIORequest->tr_node.io_Command = TR_ADDREQUEST; /* NT_UNKNOWN means unused, too (see note on exec/nodes.h) */ timerIORequest->tr_node.io_Message.mn_Node.ln_Type = NT_UNKNOWN; timerIORequest->tr_time.tv_micro = 1000000; wait_limit = timerIORequest->tr_time.tv_micro * 10; /* Default to a 10 second wait */ BeginIO((struct IORequest *)timerIORequest); /* MAIN LOOP */ while(1) { D(bug("[WaitForPort] In Wait Loop ..\n")); ULONG mask = SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | (1 << timerport->mp_SigBit); mask = Wait(mask); if (mask & SIGBREAKF_CTRL_C) break; if (mask & SIGBREAKF_CTRL_D) break; if (mask & (1 << timerport->mp_SigBit)) { D(bug("[WaitForPort] Recieved timer signal? ..\n")); timerIORequest = (struct timerequest *)GetMsg(timerport); if (timerIORequest) { AROSTCP_Port = FindPort((char *)WaitForPort_Arguments[0]); wait_time += 1000000; if (!(AROSTCP_Port)) { if (wait_time > wait_limit) { D(bug("[WaitForPort] Timeout Reached\n")); break; } D(bug("[WaitForPort] Port not found .. secs=%d\n",wait_time/1000000)); } else { D(bug("[WaitForPort] Port found ... escaping from wait loop\n")); break; } timerIORequest->tr_node.io_Command = TR_ADDREQUEST; timerIORequest->tr_time.tv_micro = 1000000; BeginIO((struct IORequest *)timerIORequest); } } } } } } /* CLEANUP */ if (timerIORequest) { TimerBase = NULL; if (timerIORequest->tr_node.io_Device != NULL) CloseDevice((struct IORequest *)timerIORequest); DeleteIORequest((struct IORequest *)timerIORequest); timerIORequest = NULL; } if (timerport) { DeleteMsgPort(timerport); timerport = NULL; } } FreeArgs(WFP_rda); } else { printf("WaitForPort: Bad Arguments .. Use 'WaitForPort ?' for correct useage\n"); } if (AROSTCP_Port) return RETURN_OK; return RETURN_WARN; }