/********************************************************************** * Chain a task by setting the calling task in a SUSPENDED state and * the called taks in the READY state. * Call the scheduler to jump the chained task. * * @param TaskID IN ID of the next task to chain * @return Status E_OK if ID is not correct * In fact the function never return **********************************************************************/ StatusType ChainTask (TaskType TaskID) { ptrTCB thisTCB; unsigned int * ptrRAM; thisTCB = GetCurrentTCB(); thisTCB->State = SUSPENDED; thisTCB = GetSpecificTCB(TaskID); if (thisTCB == NULL) return (E_OS_ID); thisTCB->State = READY; ptrRAM = thisTCB->StackAddress; if (ptrRAM != NULL) { *ptrRAM++ = (unsigned int)(thisTCB->StartAddress); *ptrRAM = 0; thisTCB->Stack_register = SREG(thisTCB->StackAddress); thisTCB->Frame_register = FREG(thisTCB->StackAddress); } DisableAllInterrupts(); kernelState |= KERNEL; kernelState &= ~USER; EnableAllInterrupts(); TaskLauncher(); return (E_OK); }
/********************************************************************** * Allow a task to terminate itself. Cannot terminate another task. * To prepare a new activation of the task, we need first to store in * stack the start adress of the task * * @param dest OUT Destination buffer * @param src IN The byte to copy * @return Status E_OK if ID is not correct * In fact the function never return **********************************************************************/ StatusType TerminateTask (void) { ptrTCB thisTCB; unsigned int * ptrRAM; thisTCB = GetCurrentTCB(); if (thisTCB->State & 0xF0) thisTCB->State -= 0x10; else thisTCB->State = SUSPENDED; ptrRAM = thisTCB->StackAddress; if (ptrRAM != NULL) { *ptrRAM++ = (unsigned int)(thisTCB->StartAddress); *ptrRAM = 0; thisTCB->Stack_register = SREG(thisTCB->StackAddress); thisTCB->Frame_register = FREG(thisTCB->StackAddress); } DisableAllInterrupts(); kernelState |= KERNEL; kernelState &= ~USER; EnableAllInterrupts(); TaskLauncher(); return (E_OK); }
static void coopth_callf(struct coopth_t *thr, struct coopth_per_thread_t *pth) { assert(!pth->data.attached); if (thr->ctxh.pre) thr->ctxh.pre(thr->tid); if (ctx_is_valid) { int ok = ctx_is_valid(); if (!ok) dosemu_error("coopth: unsafe context switch\n"); } pth->ret_cs = SREG(cs); pth->ret_ip = LWORD(eip); SREG(cs) = BIOS_HLT_BLK_SEG; LWORD(eip) = thr->hlt_off; threads_joinable++; pth->data.attached = 1; }
static void ipx_esr_call_setregs(far_t ECBPtr, u_char AXVal) { n_printf("IPX: Calling ESR at %04x:%04x of ECB at %04x:%04x\n", ECBp->ESRAddress.segment, ECBp->ESRAddress.offset, ECBPtr.segment, ECBPtr.offset); SREG(es) = ECBPtr.segment; LWORD(esi) = ECBPtr.offset; LO(ax) = AXVal; }
/************************* * Check for IPX - int 2f, AH=7A * returns AL=FF * ES:DI points to helper routine which gets to FarCallHandler *************************/ int IPXInt2FHandler(void) { LO(ax) = 0xff; SREG(es) = IPX_SEG; LWORD(edi) = IPX_OFF; n_printf("IPX: request for IPX far call handler address %x:%x\n", IPX_SEG, IPX_OFF); return 1; }
static void coopth_retf(struct coopth_t *thr, struct coopth_per_thread_t *pth) { assert(pth->data.attached); threads_joinable--; SREG(cs) = pth->ret_cs; LWORD(eip) = pth->ret_ip; if (thr->ctxh.post) thr->ctxh.post(thr->tid); pth->data.attached = 0; }
int com_dosfreemem(u_short para) { int ret = 0; pre_msdos(); HI(ax) = 0x49; SREG(es) = para; call_msdos(); if (REG(eflags) & CF) ret = -1; post_msdos(); return ret; }
static struct coopth_t *on_thread(void) { int i; if (SREG(cs) != BIOS_HLT_BLK_SEG) return NULL; for (i = 0; i < threads_active; i++) { int tid = active_tids[i]; if (LWORD(eip) == coopthreads[tid].hlt_off) return &coopthreads[tid]; } return NULL; }
static int load_and_run_DOS_program(char *command, char *cmdline, int quit) { BMEM(pa4) = (struct param4a *)lowmem_alloc(sizeof(struct param4a)); if (!BMEM(pa4)) return -1; BMEM(allocated) = 1; BMEM(quit) = quit; BMEM(cmd) = com_strdup(command); if (!BMEM(cmd)) { com_errno = 8; return -1; } BMEM(cmdl) = lowmem_alloc(256); if (!BMEM(cmdl)) { com_strfree(BMEM(cmd)); com_errno = 8; return -1; } if (!cmdline) cmdline = ""; snprintf(BMEM(cmdl), 256, "%c %s\r", (char)(strlen(cmdline)+1), cmdline); /* prepare param block */ BMEM(pa4)->envframe = 0; // ctcb->envir_frame; BMEM(pa4)->cmdline = MK_FARt(DOSEMU_LMHEAP_SEG, DOSEMU_LMHEAP_OFFS_OF(BMEM(cmdl))); BMEM(pa4)->fcb1 = MK_FARt(COM_PSP_SEG, offsetof(struct PSP, FCB1)); BMEM(pa4)->fcb2 = MK_FARt(COM_PSP_SEG, offsetof(struct PSP, FCB2)); SREG(es) = DOSEMU_LMHEAP_SEG; LWORD(ebx) = DOSEMU_LMHEAP_OFFS_OF(BMEM(pa4)); /* path of programm to load */ SREG(ds) = DOSEMU_LMHEAP_SEG; LWORD(edx) = DOSEMU_LMHEAP_OFFS_OF(BMEM(cmd)); fake_call_to(BIOSSEG, GET_RETCODE_HELPER); LWORD(eax) = 0x4b00; real_run_int(0x21); return 0; }
lnaddr_t seg_translate(swaddr_t swaddr, uint8_t sreg) { // Log("swaddr = 0x%x", swaddr); Assert(cpu.cr0.protect_enable, "CR0 protect enable bit is not set!"); // Log("segment"); uint32_t segdesc_addr = cpu.gdtr.base + SREG(sreg).index; // Log("addr = 0x%x", segdesc_addr); SegDesc *segdesc = (SegDesc *)malloc(sizeof(SegDesc)); segdesc->val[0] = lnaddr_read(segdesc_addr, 4); segdesc->val[1] = lnaddr_read(segdesc_addr + 4, 4); // int i; // for(i = 0; i < 2; ++i) // Log("segdesc: 0x%08x", segdesc->val[i]); uint32_t lnaddr = swaddr + (segdesc->base_31_24 << 24) + (segdesc->base_23_16 << 16) + segdesc->base_15_0; // Log("lnaddr = 0x%x", lnaddr); // Assert(swaddr == lnaddr, "swaddr == lnaddr"); return lnaddr; }
int com_dossetcurrentdir(char *path) { /*struct com_starter_seg *ctcb = owntcb->params;*/ char *s = com_strdup(path); com_errno = 8; if (!s) return -1; pre_msdos(); HI(ax) = 0x3b; SREG(ds) = DOSEMU_LMHEAP_SEG; LWORD(edx) = DOSEMU_LMHEAP_OFFS_OF(s); call_msdos(); /* call MSDOS */ com_strfree(s); if (LWORD(eflags) & CF) { post_msdos(); return -1; } post_msdos(); return 0; }
/* * Set a register (r < 256) * if it's an IO register (> 31) also (try to) call any callback that was * registered to track changes to that register. */ static inline void _avr_set_r(avr_t * avr, uint8_t r, uint8_t v) { REG_TOUCH(avr, r); if (r == R_SREG) { avr->data[R_SREG] = v; // unsplit the SREG SET_SREG_FROM(avr, v); SREG(); } if (r > 31) { uint8_t io = AVR_DATA_TO_IO(r); if (avr->io[io].w.c) avr->io[io].w.c(avr, r, v, avr->io[io].w.param); else avr->data[r] = v; if (avr->io[io].irq) { avr_raise_irq(avr->io[io].irq + AVR_IOMEM_IRQ_ALL, v); for (int i = 0; i < 8; i++) avr_raise_irq(avr->io[io].irq + i, (v >> i) & 1); }
unsigned int mhp_debug(enum dosdebug_event code, unsigned int parm1, unsigned int parm2) { int rtncd = 0; #if 0 return rtncd; #endif mhpdbgc.currcode = code; mhp_bpclr(); switch (DBG_TYPE(mhpdbgc.currcode)) { case DBG_INIT: mhp_init(); break; case DBG_BOOT: mhp_boot(); break; case DBG_INTx: if (!mhpdbg.active) break; if (test_bit(DBG_ARG(mhpdbgc.currcode), mhpdbg.intxxtab)) { if ((mhpdbgc.bpload==1) && (DBG_ARG(mhpdbgc.currcode) == 0x21) && (LWORD(eax) == 0x4b00) ) { /* mhpdbgc.bpload_bp=((long)SREG(cs) << 4) +LWORD(eip); */ mhpdbgc.bpload_bp = SEGOFF2LINEAR(SREG(cs), LWORD(eip)); if (mhp_setbp(mhpdbgc.bpload_bp)) { mhp_printf("bpload: intercepting EXEC\n", SREG(cs), REG(eip)); /* mhp_cmd("r"); mhp_cmd("d ss:sp 30h"); */ mhpdbgc.bpload++; mhpdbgc.bpload_par=MK_FP32(BIOSSEG,(long)DBGload_parblock-(long)bios_f000); MEMCPY_2UNIX(mhpdbgc.bpload_par, SEGOFF2LINEAR(SREG(es), LWORD(ebx)), 14); MEMCPY_2UNIX(mhpdbgc.bpload_cmdline, PAR4b_addr(commandline_ptr), 128); MEMCPY_2UNIX(mhpdbgc.bpload_cmd, SEGOFF2LINEAR(SREG(ds), LWORD(edx)), 128); SREG(es)=BIOSSEG; LWORD(ebx)=(void *)mhpdbgc.bpload_par - MK_FP32(BIOSSEG, 0); LWORD(eax)=0x4b01; /* load, but don't execute */ } else { mhp_printf("bpload: ??? #1\n"); mhp_cmd("r"); mhpdbgc.bpload_bp=0; mhpdbgc.bpload=0; } if (!--mhpdbgc.int21_count) { volatile register int i=0x21; /* beware, set_bit-macro has wrong constraints */ clear_bit(i, mhpdbg.intxxtab); if (test_bit(i, mhpdbgc.intxxalt)) { clear_bit(i, mhpdbgc.intxxalt); reset_revectored(i, &vm86s.int_revectored); } } } else { if ((DBG_ARG(mhpdbgc.currcode) != 0x21) || !mhpdbgc.bpload ) { mhpdbgc.stopped = 1; if (parm1) LWORD(eip) -= 2; mhpdbgc.int_handled = 0; mhp_poll(); if (mhpdbgc.int_handled) rtncd = 1; else if (parm1) LWORD(eip) += 2; } } } break; case DBG_INTxDPMI: if (!mhpdbg.active) break; mhpdbgc.stopped = 1; #if WITH_DPMI dpmi_mhp_intxxtab[DBG_ARG(mhpdbgc.currcode) & 0xff] &= ~2; #endif break; case DBG_TRAP: if (!mhpdbg.active) break; if (DBG_ARG(mhpdbgc.currcode) == 1) { /* single step */ switch (mhpdbgc.trapcmd) { case 2: /* t command -- step until IP changes */ if (mhpdbgc.trapip == mhp_getcsip_value()) break; /* no break */ case 1: /* ti command */ mhpdbgc.trapcmd = 0; rtncd = 1; mhpdbgc.stopped = 1; break; } if (traceloop && mhp_bpchk(mhp_getcsip_value())) { traceloop = 0; loopbuf[0] = '\0'; } } if (DBG_ARG(mhpdbgc.currcode) == 3) { /* int3 (0xCC) */ int ok=0; unsigned int csip=mhp_getcsip_value() - 1; if (mhpdbgc.bpload_bp == csip ) { /* mhp_cmd("r"); */ mhp_clearbp(mhpdbgc.bpload_bp); mhp_modify_eip(-1); if (mhpdbgc.bpload == 2) { mhp_printf("bpload: INT3 caught\n"); SREG(cs)=BIOSSEG; LWORD(eip)=(long)DBGload-(long)bios_f000; mhpdbgc.trapcmd = 1; mhpdbgc.bpload = 0; } } else { if ((ok=mhp_bpchk( csip))) { mhp_modify_eip(-1); } else { if ((ok=test_bit(3, mhpdbg.intxxtab))) { /* software programmed INT3 */ mhp_modify_eip(-1); mhp_cmd("r"); mhp_modify_eip(+1); } } } if (ok) { mhpdbgc.trapcmd = 0; rtncd = 1; mhpdbgc.stopped = 1; } } break; case DBG_PRE_VM86: mhp_pre_vm86(); break; case DBG_POLL: mhp_poll(); break; case DBG_GPF: if (!mhpdbg.active) break; mhpdbgc.stopped = 1; mhp_poll(); break; default: break; } if (mhpdbg.active) mhp_bpset(); return rtncd; }
int ipx_int7a(void) { u_short port; /* port here means DOS IPX socket */ u_short newPort; u_char *AddrPtr; far_t ECBPtr; unsigned long network; int hops, ticks; n_printf("IPX: request number 0x%x\n", LWORD(ebx)); switch (LWORD(ebx)) { case IPX_OPEN_SOCKET: if (LO(ax) != 0xff) n_printf("IPX: OpenSocket: longevity flag (%#x) not supported\n", LO(ax)); port = LWORD(edx); newPort = 0; LO(ax) = IPXOpenSocket(port, &newPort); if (LO(ax) == RCODE_SUCCESS) LWORD(edx) = newPort; break; case IPX_CLOSE_SOCKET: port = LWORD(edx); LO(ax) = IPXCloseSocket(port); break; case IPX_GET_LOCAL_TARGET: /* do nothing here because routing is handled by IPX */ /* normally this would return an ImmediateAddress, but */ /* the ECB ImmediateAddress is never used, so just return */ network = READ_DWORD(SEGOFF2LINEAR(SREG(es), LWORD(esi))); n_printf("IPX: GetLocalTarget for network %08lx\n", network ); if( network==0 || memcmp(&network, MyAddress, 4) == 0 ) { n_printf("IPX: returning GLT success for local address\n"); LO(ax) = RCODE_SUCCESS; LWORD(ecx) = 1; } else { if( IPXGetLocalTarget( network, &hops, &ticks )==0 ) { LO(ax) = RCODE_SUCCESS; LWORD(ecx) = ticks; } else { n_printf("IPX: GetLocalTarget failed.\n"); LO(ax) = RCODE_CANNOT_FIND_ROUTE; } } break; case IPX_FAST_SEND: n_printf("IPX: fast send\n"); /* just fall through to regular send */ case IPX_SEND_PACKET: { int ret; ECBPtr.segment = SREG(es); ECBPtr.offset = LWORD(esi); n_printf("IPX: send packet ECB at %p\n", ECBp); /* What the hell is the async send? Do it synchroniously! */ ret = IPXSendPacket(ECBPtr); if ((ret == RCODE_SUCCESS) && FARt_PTR2(ECBp->ESRAddress)) ipx_esr_call(ECBPtr, ESR_CALLOUT_IPX); LO(ax) = ret; break; } case IPX_LISTEN_FOR_PACKET: ECBPtr.segment = SREG(es); ECBPtr.offset = LWORD(esi); n_printf("IPX: listen for packet, ECB at %x:%x\n", ECBPtr.segment, ECBPtr.offset); /* put this packet on the queue of listens for this socket */ LO(ax) = IPXListenForPacket(ECBPtr); break; case IPX_SCHEDULE_IPX_EVENT: ECBPtr.segment = SREG(es); ECBPtr.offset = LWORD(esi); n_printf("IPX: schedule IPX event for ECB at %x:%x\n", ECBPtr.segment, ECBPtr.offset); /* put this packet on the queue of AES events for this socket */ LO(ax) = IPXScheduleEvent(ECBPtr, IU_ECB_IPX_WAITING, LWORD(eax)); break; case IPX_CANCEL_EVENT: ECBPtr.segment = SREG(es); ECBPtr.offset = LWORD(esi); n_printf("IPX: cancel event for ECB at %p\n", ECBp); LO(ax) = IPXCancelEvent(ECBPtr); break; case IPX_SCHEDULE_AES_EVENT: ECBPtr.segment = SREG(es); ECBPtr.offset = LWORD(esi); n_printf("IPX: schedule AES event ECB at %p\n", FARt_PTR2(ECBPtr)); /* put this packet on the queue of AES events for this socket */ LO(ax) = IPXScheduleEvent(ECBPtr, IU_ECB_AES_WAITING, LWORD(eax)); break; case IPX_GET_INTERVAL_MARKER: /* Note that timerticks is actually an unsigned long in BIOS */ /* this works because of intel lo-hi architecture */ LWORD(eax) = READ_WORD(BIOS_TICK_ADDR); n_printf("IPX: get interval marker %d\n", LWORD(eax)); /* n_printf("IPX: doing extra relinquish control\n"); */ IPXRelinquishControl(); break; case IPX_GET_INTERNETWORK_ADDRESS: n_printf("IPX: get internetwork address\n"); AddrPtr = SEG_ADR((u_char *), es, si); memcpy(AddrPtr, MyAddress, 10); break; case IPX_RELINQUISH_CONTROL: n_printf("IPX: relinquish control\n"); IPXRelinquishControl(); break; case IPX_DISCONNECT: n_printf("IPX: disconnect\n"); break; case IPX_SHELL_HOOK: n_printf("IPX: shell hook\n"); break; case IPX_GET_MAX_PACKET_SIZE: n_printf("IPX: get max packet size\n"); /* return max data size in AX, and suggested retries in CL */ /* DANG_FIXTHIS - return a real max packet size here */ LWORD(eax) = 1024; /* must be a power of 2 */ LO(cx) = 20; break; case IPX_GET_MEDIA_DATA_SIZE: n_printf("IPX: get max packet size\n"); /* return max data size in AX, and suggested retries in CL */ /* DANG_FIXTHIS - return a real max media size here */ LWORD(eax) = 1480; LO(cx) = 20; break; case IPX_CLEAR_SOCKET: n_printf("IPX: clear socket\n"); break; default: n_printf("IPX: Unimplemented function.\n"); break; } return 1; }
u_int __attribute__((__section__(".stack_tsk1"))) stack1[DEFAULT_STACK_SIZE]; u_int __attribute__((__section__(".stack_tsk2"))) stack2[DEFAULT_STACK_SIZE]; u_int __attribute__((__section__(".stack_tsk3"))) stack3[DEFAULT_STACK_SIZE]; u_int __attribute__((__section__(".stack_tsk4"))) stack4[128]; /********************************************************************** * ---------------------- TASK DESCRIPTOR SECTION --------------------- **********************************************************************/ const unsigned int descromarea; const TCB TCB_const_list[] = { /******************************************************************* * -------------------------- Task 0 ------------------------------- *******************************************************************/ { SREG(stack0), /* Stack_register */ FREG(stack0), /* Frame_register */ TASK0, /* StartAddress */ stack0, /* StackAddress */ sizeof(stack0), /* StackSize */ TASK0_ID, /* TaskID */ TASK0_PRIO, /* Priority */ NONE, /* EventWaited */ NONE, /* EventReceived */ READY, /* State */ EXTENDED, /* Type */ 0, /* Time */ 0, /* kernelState_copy */ NULL /* next */ }, /*******************************************************************