void main() { union REGS r; struct SREGS s; s.ds = s.es = s.fs = s.gs = FP_SEG( &s ); #if defined(__PHARLAP__) r.w.ax = 0x2503; /* get real-mode vector */ r.h.cl = 0x33; /* interrupt vector 0x33 */ int386( 0x21, &r, &r ); printf( "mouse handler real-mode address=" "%lx\n", r.x.ebx ); r.w.ax = 0x2502; /* get protected-mode vector */ r.h.cl = 0x33; /* interrupt vector 0x33 */ int386x( 0x21, &r, &r, &s ); printf( "mouse handler protected-mode address=" "%x:%lx\n", s.es, r.x.ebx ); #else r.h.ah = 0x35; /* get vector */ r.h.al = 0x33; /* vector 0x33 */ int386x( 0x21, &r, &r, &s ); printf( "mouse handler protected-mode address=" "%x:%lx\n", s.es, r.x.ebx ); #endif }
T_void IMouseInstallCallback(T_void) { struct SREGS sregs ; union REGS inregs ; union REGS outregs ; /* Can't get to work correctly -- take it out. */ //return ; DebugRoutine("IMouseInstallCallback") ; if (G_callbackInstalled == FALSE) { puts("Installing mouse callback") ; segread(&sregs) ; inregs.w.ax = 0xC ; inregs.w.cx = 0x000F ; inregs.x.edx = FP_OFF(IMouseCallback) ; sregs.es = FP_SEG(IMouseCallback) ; int386x(0x33, &inregs, &outregs, &sregs) ; G_callbackInstalled = TRUE ; /* Make sure the callback is removed at some time. */ if (G_atexitInstalled == FALSE) { G_atexitInstalled = TRUE ; atexit(IMouseUninstallCallback) ; } } DebugEnd() ; }
MouseScr::MouseScr() { union { REGS inRegs; REGS outRegs; }; SREGS sRegs; // Setup the interrupt routine memset(&sRegs, NULL, sizeof(SREGS)); memset(&inRegs, NULL, sizeof(REGS)); inRegs.x.eax = 0x000C; inRegs.x.ecx = BTNS_UP_DOWN; functionPtr = MouseInterrupt; inRegs.x.edx = FP_OFF(functionPtr); sRegs.es = FP_SEG(functionPtr); int386x(INT_MOUSE, &inRegs, &outRegs, &sRegs); // mouse_init will show the driver pointer. // Since we are going to display the pointer using // animate, let's hide the mouse driver's pointer #pragma aux MOUSE_INIT = \ "mov ax, 2" \ "int 33h"; // set priority to be on top of everything SetPri(9999); }
void MouseInt (struct rminfo *prmi) { memset (&sregs, 0, sizeof (sregs)); AX (regs) = 0x0300; // DPMI: simulate interrupt BX (regs) = MOUSE_INT; CX (regs) = 0; DI (regs) = FP_OFF (prmi); sregs.es = FP_SEG (prmi); int386x( DPMI_INT, ®s, ®s, &sregs ); }
/* execute real mode interrupt from protected mode */ static int RM_Interrupt(int num, RM_Info *rm) { union REGS regs{}; struct SREGS sregs{}; segread(&sregs); regs.w.ax = 0x0300; regs.w.bx = (short)num; regs.w.cx = 0; sregs.es = FP_SEG(rm); regs.x.edi = FP_OFF(rm); return int386x(0x31, ®s, ®s, &sregs); }
void read_mem_info() { union REGS regs; struct SREGS sregs; regs.x.eax = 0x00000500; memset( &sregs, 0, sizeof(sregs) ); sregs.es = FP_SEG( &MemInfo ); regs.x.edi = FP_OFF( &MemInfo ); int386x( DPMI_INT, ®s, ®s, &sregs ); }
// setup the vector to Mayday() routine when croaker() faults void setup(void) { struct SREGS sregs; union REGS regs; segread(&sregs); sregs.ds=FP_SEG(Mayday); // vector address regs.x.esi=FP_OFF(Mayday); sregs.es=FP_SEG(&InfoList); // info dump address regs.x.edi=FP_OFF(&InfoList); regs.h.cl=1; // 32-bit routine regs.w.ax=0xff31; // UserErrTerm int386x(0x31,®s,®s,&sregs); regs.w.ax=0xff30; // SetDump regs.h.cl=0; int386(0x31,®s,®s); }
void mouse_close() { struct SREGS sregs; union REGS inregs, outregs; if (Mouse_installed) { Mouse_installed = 0; // clear mouse handler by setting flags to 0. memset( &inregs, 0, sizeof(inregs)); memset( &sregs, 0, sizeof(sregs)); inregs.w.ax = 0xC; inregs.w.cx = 0; // disable event handler by setting to zero. inregs.x.edx = 0; sregs.es = 0; int386x(0x33, &inregs, &outregs, &sregs); } }
void dpmi_real_int386x( ubyte intno, dpmi_real_regs * rregs ) { union REGS regs; struct SREGS sregs; /* Use DMPI call 300h to issue the DOS interrupt */ dpmi_setup_stack(rregs); memset(®s,0,sizeof(regs)); memset(&sregs,0,sizeof(sregs)); regs.w.ax = 0x0300; regs.h.bl = intno; regs.h.bh = 0; regs.w.cx = 0; sregs.es = FP_SEG(rregs); regs.x.edi = FP_OFF(rregs); int386x( 0x31, ®s, ®s, &sregs ); }
T_word32 FreeMemory(T_void) { #if defined(DOS32) T_word32 memInfo[12] ; union REGS regs ; struct SREGS sregs ; regs.x.eax = 0x500 ; memset(&sregs, 0, sizeof(sregs)) ; sregs.es = FP_SEG(memInfo) ; regs.x.edi = FP_OFF(memInfo) ; int386x(0x31, ®s, ®s, &sregs) ; return (memInfo[0] + _memavl()) ; #else return 100000000; // TODO: don't really know #endif }
void dpmi_real_call(dpmi_real_regs * rregs) { union REGS regs; struct SREGS sregs; dpmi_setup_stack(rregs); /* Use DMPI call 301h to call real mode procedure */ memset(®s,0,sizeof(regs)); memset(&sregs,0,sizeof(sregs)); regs.w.ax = 0x0301; regs.h.bh = 0; regs.w.cx = 0; sregs.es = FP_SEG(rregs); regs.x.edi = FP_OFF(rregs); int386x( 0x31, ®s, ®s, &sregs ); if ( regs.x.cflag ) exit(regs.w.ax); }
/* ** pciPhrlapMapPhysMemEndSegment (_dx_map_phys) */ int pciPhrlapMapPhysMemEndSegment( USHORT selector, ULONG phys_addr, ULONG page_cnt, ULONG* offsetp ) { union REGS r; struct SREGS sr; /* ** Phar Lap 250ah - Map Physical Memory at End of Segment */ r.w.ax = 0x250a; /* ** ES segment selector in the LDT of segment to modify ** EBX physical base address of memory to map, must be a multiple of four kilobytes ** ECX number of physical 4-KB memory pages to map */ r.x.ebx = (unsigned int) phys_addr; r.x.ecx = (unsigned int) page_cnt; segread( &sr ); sr.es = selector; int386x( PHARLAP_INTERRUPT, &r, &r, &sr ); if ( r.w.cflag ) { /* ** EAX error code */ return r.x.eax; } else { /* ** EAX offset in segment of mapped memory */ *offsetp = (ULONG) r.x.eax; return 0; } }
void main (int argc, char *argv[]) { union REGS r; DPMI_CALLREGS dr; struct SREGS sr; char *lowp; unsigned short __far *alias; void far *fh; WORD orig_rm_seg; WORD orig_rm_off; DWORD orig_pm_off; WORD orig_pm_sel; int c; int doprot = 1; int doreal = 1; while (argc-- > 1) { if (argv[argc][0] != '-') { badarg: printf ("Invalid argument '%s'\n", argv[argc]); printf ("Valid options are:\n"); printf ("\t-p Don't install protected mode handler\n"); printf ("\t-r Don't install real mode handler\n"); printf ("\t-2 Use COM2 instead of COM1 for testing\n"); exit (1); } switch (argv[argc][1]) { case 'p': { doprot = 0; printf ("Not hooking in protected mode\n"); break; } case 'r': { doreal = 0; printf ("Not hooking in real mode\n"); break; } case '2': { com_id = 2; com_int = 0x0B; com_port = 0x2F8; printf ("Using COM2 instead of COM1 for testing\n"); break; } default: goto badarg; } if (argv[argc][2]) goto badarg; } /* Save the starting real-mode and protected-mode handler addresses. */ r.x.eax = 0x0204; /* DPMI get protected mode vector */ r.h.bl = com_int; int386 (0x31, &r, &r); orig_pm_sel = (WORD) r.x.ecx; orig_pm_off = r.x.edx; r.x.eax = 0x0200; /* DPMI get real mode vector */ r.h.bl = com_int; int386 (0x31, &r, &r); orig_rm_seg = (WORD) r.x.ecx; orig_rm_off = (WORD) r.x.edx; /* Patch the code of the real mode handler so it knows which com port is doing the communications. This is done before the handler is copied low, to take advantage of the label "com_port_low" while it's still valid. */ alias = &com_port_low; fh = (void __far *) &com_port; *(alias = MK_FP(FP_SEG(fh), FP_OFF(alias))) = com_port; /* Allocate 128 bytes of DOS memory for the real-mode handler, which must of course be less than 128 bytes long, plus 1029 bytes for the data. Then copy the real-mode handler to DOS memory and initialize the data to zero. */ if (! (lowp = D32DosMemAlloc (128 + 4 + 1024 + 1, &lowmem_seg))) { printf ("Couldn't get low memory!\n"); exit (1); } _fmemcpy ((char __far *) lowp, (void __far *) rmhandler, 128); _fmemset ((char __far *) lowp + 128, 0, 4 + 1024 + 1); fh = (void __far *) pmhandler; /* Install the new handlers. The memory touched by the protected mode handler needs to be locked, in case we are running under VMM or an external DPMI host. */ if (doprot) { r.x.eax = 0x0205; /* DPMI set protected mode vector */ r.x.ebx = (DWORD) com_int; r.x.ecx = (DWORD) FP_SEG(fh); r.x.edx = FP_OFF(fh); int386 (0x31, &r, &r); r.x.eax = 0x0600; /* DPMI lock linear region */ r.x.ebx = ((DWORD) pmhandler) >> 16; r.x.ecx = ((DWORD) pmhandler) & 0xFFFF; r.x.esi = 0; r.x.edi = 256; /* lock 256 bytes */ int386 (0x31, &r, &r); r.x.eax = 0x0600; r.x.ebx = ((DWORD) &com_port) >> 16; r.x.ecx = ((DWORD) &com_port) & 0xFFFF; r.x.esi = 0; r.x.edi = sizeof(WORD); /* lock 2 bytes */ int386 (0x31, &r, &r); } if (doreal) { r.x.eax = 0x0201; /* DPMI set real mode vector */ r.x.ebx = (DWORD) com_int; r.x.ecx = D32RealSeg(lowp); /* CX:DX == real mode &handler */ r.x.edx = D32RealOff(lowp); int386 (0x31, &r, &r); } /* Initialize COM port. */ com_init (); puts ("Move the mouse or transmit data; press ESC to cancel\n"); /* Wait for the ESC key to be pressed. This loop has a good mix of time spent in real mode and protected mode, so the upper left hand corner of your color screen will toggle between 'R' and 'P'. */ while (1) { /* Explicitly go down to real mode to ask if a key is ready. (The kbhit() call is simpler to code, but extra transfers to real mode may be optimized out by the DOS extender.) */ r.x.eax = 0x300; /* DPMI signal real mode interrupt */ r.x.ebx = 0x16; r.x.ecx = 0; fh = (void far *) &dr; _fmemset (fh, 0, sizeof(DPMI_CALLREGS)); dr.eax = 0x0100; sr.ds = 0; sr.es = FP_SEG(fh); r.x.edi = FP_OFF(fh); int386x (0x31, &r, &r, &sr); if (! (dr.flags & 0x40)) /* Test zero flag */ { if (((c = getch ()) & 0xff) == 27) break; putch (c); } /* Here we just check for an overflow, update our count of interrupts, and reset the buffer. You would process the data before flushing the buffer. */ _disable (); if (*(lowp + 128 + 4 + 1024)) /* Overflow? */ break; total_count += *((unsigned long *)(lowp + 128)); *((unsigned long *)(lowp + 128)) = 0; _enable (); } /* Clean up. */ r.x.eax = 0x0201; /* DPMI set real mode vector */ r.x.ebx = (DWORD) com_int; r.x.ecx = (DWORD) orig_rm_seg; /* CX:DX == real mode &handler */ r.x.edx = (DWORD) orig_rm_off; int386 (0x31, &r, &r); r.x.eax = 0x0205; /* DPMI set protected mode vector */ r.x.ebx = (DWORD) com_int; r.x.ecx = (DWORD) orig_pm_sel; r.x.edx = orig_pm_off; int386 (0x31, &r, &r); if (*(lowp + 128 + 4 + 1024)) printf ("\nOverflow! Increase data receive buffer size or check the\nbuffer more often.\n"); else printf ("\n%lu interrupts processed (%lu in protected mode, %lu real mode).\n", total_count, pm_count, total_count - pm_count); }
/* init_mouse: * Helper for initialising the int 0x33 driver and installing an RMCB. */ static int init_mouse(void (*handler)(__dpmi_regs *r)) { __dpmi_regs r; int num_buttons; /* initialise the int 0x33 driver */ r.x.ax = 0; __dpmi_int(0x33, &r); if (r.x.ax == 0) return -1; num_buttons = r.x.bx; if (num_buttons == 0xFFFF) num_buttons = 2; /* create and activate a real mode callback */ if (handler) { LOCK_VARIABLE(mouse_regs); #ifdef ALLEGRO_DJGPP /* djgpp version uses libc routines to set up the RMCB */ { LOCK_VARIABLE(mouse_seginfo); mouse_seginfo.pm_offset = (int)handler; mouse_seginfo.pm_selector = _my_cs(); if (_go32_dpmi_allocate_real_mode_callback_retf(&mouse_seginfo, &mouse_regs) != 0) return -1; r.x.ax = 0x0C; r.x.cx = 0x7F; r.x.dx = mouse_seginfo.rm_offset; r.x.es = mouse_seginfo.rm_segment; __dpmi_int(0x33, &r); } #elif defined ALLEGRO_WATCOM /* Watcom version relies on the DOS extender to do it for us */ { struct SREGS sregs; union REGS inregs, outregs; inregs.w.ax = 0x0C; inregs.w.cx = 0x7F; inregs.x.edx = _allocate_real_mode_callback(handler, &mouse_regs); segread(&sregs); sregs.es = _my_cs(); int386x(0x33, &inregs, &outregs, &sregs); } #else #error unknown platform #endif } return num_buttons; }
int dpmi_init(int verbose) { union REGS regs; struct SREGS sregs; mem_data mi; dpmi_dos_memory = dpmi_find_dos_memory(); dpmi_dos_buffer = dpmi_real_malloc( 1024, &dpmi_dos_selector); if (!dpmi_dos_buffer) { dpmi_dos_selector = 0; printf( "Error allocating 1K of DOS memory\n" ); exit(1); } atexit(dpmi_close); // Check dpmi memset(®s,0,sizeof(regs)); regs.x.eax = 0x400; // DPMI Get Memory Info int386( 0x31, ®s, ®s ); if (!regs.w.cflag) { if (verbose) printf( "V%d.%d, CPU:%d, VMM:", regs.h.ah, regs.h.al, regs.h.cl ); if (regs.w.bx & 4) { if (verbose) printf( "1" ); dpmi_virtual_memory = 1; } else { if (verbose) printf( "0" ); } } //--------- Find available memory memset(®s,0,sizeof(regs)); memset(&sregs,0,sizeof(sregs)); regs.x.eax = 0x500; // DPMI Get Memory Info sregs.es = FP_SEG(&mi); regs.x.edi = FP_OFF(&mi); int386x( 0x31, ®s, ®s, &sregs ); if (!regs.w.cflag) { if (verbose) printf( ", P:%dK", mi.largest_lockable_pages*4 ); if (dpmi_virtual_memory) if (verbose) printf( ", A:%dK", mi.largest_block_bytes/1024 ); //dpmi_physical_memory = mi.largest_lockable_pages*4096; //dpmi_available_memory = mi.largest_block_bytes; dpmi_physical_memory = mi.total_physical_pages*4096; dpmi_available_memory = mi.total_pages * 4096; } else { if (verbose) printf( "MemInfo failed!" ); dpmi_physical_memory = 16*1024*1024; // Assume 16 MB dpmi_available_memory = 16*1024*1024; // Assume 16 MB } #ifdef __WATCOMC__ if (!dpmi_lock_region( _GETDS, 4096 )) { printf( "Error locking _GETDS" ); exit(1); } if (!dpmi_lock_region( cstart_, 4096 )) { printf( "Error locking cstart" ); exit(1); } if (!dpmi_lock_region( _chain_intr, 4096 )) { printf( "Error locking _chain_intr" ); exit(1); } #endif return 1; }
void main() { union REGS regs; struct SREGS sregs; int interrupt_no=0x31; short selector; short segment; char far *str; /* DPMI call 100h allocates DOS memory */ memset(&sregs,0,sizeof(sregs)); regs.w.ax=0x0100; regs.w.bx=0x0004; int386x( interrupt_no, ®s, ®s, &sregs); segment=regs.w.ax; selector=regs.w.dx; /* Move string to DOS real-mode memory */ str=MK_FP(selector,0); cdRequest = (struct cd_request far *)memory; // cdRequestSegment = FP_SEG(memory); cdRequestSegment = segment; cdRequestOffset = FP_OFF(memory); readInfo = (union readInfo_u far *)(memory + sizeof(struct cd_request)); readInfoSegment = cdRequestSegment; readInfoOffset = FP_OFF(memory + sizeof(struct cd_request)); /* Set up real-mode call structure */ cdRequest->headerLength = 13; cdRequest->unit = 0; cdRequest->command = COMMAND_WRITE; cdRequest->status = 0; cdRequest->x.write.mediaDescriptor = 0; cdRequest->x.write.bufferOffset = readInfoOffset; cdRequest->x.write.bufferSegment = readInfoSegment; cdRequest->x.write.length = sizeof(struct reset_s); cdRequest->x.write.startSector = 0; cdRequest->x.write.volumeID = 0; readInfo->reset.code = WRITE_REQUEST_EJECT; _fmemcpy( str, (char far *)cdRequest, sizeof(struct cd_request)); /* Set up real-mode call structure */ memset(&RMI,0,sizeof(RMI)); RMI.EAX=0x1510; RMI.ECX=3; RMI.ES = segment; RMI.EBX = 0; //Use DPMI call 300h to issue the DOS interrupt regs.w.ax = 0x0300; regs.h.bl = 0x2f; regs.h.bh = 0; regs.w.cx = 0; sregs.es = FP_SEG(&RMI); regs.x.edi = FP_OFF(&RMI); int386x( interrupt_no, ®s, ®s, &sregs ); }
//-------------------------------------------------------- // returns 0 if no mouse // else number of buttons int mouse_init(int enable_cyberman) { dpmi_real_regs rr; cyberman_info *ci; struct SREGS sregs; union REGS inregs, outregs; ubyte *Mouse_dos_mem; if (Mouse_installed) return Mouse.num_buttons; if (_dos_getvect(0x33) == NULL) { // No mouse driver loaded return 0; } // Reset the mouse driver memset( &inregs, 0, sizeof(inregs) ); inregs.w.ax = 0; int386(0x33, &inregs, &outregs); if (outregs.w.ax != 0xffff) return 0; Mouse.num_buttons = outregs.w.bx; Mouse.cyberman = 0; // Enable mouse driver memset( &inregs, 0, sizeof(inregs) ); inregs.w.ax = 0x0020; int386(0x33, &inregs, &outregs); if (outregs.w.ax != 0xffff ) return 0; if ( enable_cyberman ) { Mouse_dos_mem = dpmi_get_temp_low_buffer( 64 ); if (Mouse_dos_mem==NULL) { printf( "Unable to allocate DOS buffer in mouse.c\n" ); } else { // Check for Cyberman... memset( &rr, 0, sizeof(dpmi_real_regs) ); rr.es = DPMI_real_segment(Mouse_dos_mem); rr.edx = DPMI_real_offset(Mouse_dos_mem); rr.eax = 0x53c1; dpmi_real_int386x( 0x33, &rr ); if (rr.eax==1) { // SWIFT functions supported ci = (cyberman_info *)Mouse_dos_mem; if (ci->device_type==1) { // Cyberman Mouse.cyberman = 1; //printf( "Cyberman mouse detected\n" ); Mouse.num_buttons = 11; } } } } if (!dpmi_lock_region(&Mouse,sizeof(mouse_info))) { Error( "Unable to lock mouse data region" ); } if (!dpmi_lock_region((void near *)mouse_handler,(char *)mouse_handler_end - (char near *)mouse_handler)) { Error( "Unable to lock mouse handler" ); } // Install mouse handler memset( &inregs, 0, sizeof(inregs)); memset( &sregs, 0, sizeof(sregs)); inregs.w.ax = 0xC; inregs.w.cx = ME_LB_P|ME_LB_R|ME_RB_P|ME_RB_R|ME_MB_P|ME_MB_R; // watch all 3 button ups/downs if (Mouse.cyberman) inregs.w.cx |= ME_Z_C| ME_P_C| ME_B_C| ME_H_C; // if using a cyberman, also watch z, pitch, bank, heading. inregs.x.edx = FP_OFF(mouse_handler); sregs.es = FP_SEG(mouse_handler); int386x(0x33, &inregs, &outregs, &sregs); Mouse_installed = 1; atexit( mouse_close ); mouse_flush(); return Mouse.num_buttons; }
int GetCountryCode (void) { #if (DOSX & DJGPP) /* _osmajor/_osminor not set in crt0.o */ _get_dos_version (0); #endif if (_osmajor >= 3) { #if (DOSX & DJGPP) __dpmi_regs reg; reg.d.edx = 0; reg.x.ds = __tb / 16; reg.d.eax = 0x3800; __dpmi_int (0x21, ®); if (reg.x.flags & 1) return (0); dosmemget (__tb, sizeof(_country_info), &_country_info); return (reg.x.bx); #elif (DOSX & PHARLAP) SWI_REGS reg; if (_watt_dosTbSize < sizeof(_country_info)) return (0); reg.edx = RP_OFF (_watt_dosTbr); reg.ds = RP_SEG (_watt_dosTbr); reg.eax = 0x3800; _dx_real_int (0x21, ®); if (reg.flags & 1) return (0); ReadRealMem (&_country_info, _watt_dosTbr, sizeof(_country_info)); return (reg.ebx); #elif (DOSX & (DOS4GW|WDOSX)) union REGS reg; struct SREGS sreg; if (_watt_dosTbSize < sizeof(_country_info)) return (0); reg.x.edx = 0; sreg.ds = _watt_dosTbSeg; reg.x.eax = 0x3800; int386x (0x21, ®, ®, &sreg); if (reg.x.cflag) return (0); memcpy (&_country_info, SEG_OFS_TO_LIN(_watt_dosTbSeg,0), sizeof(_country_info)); return (reg.w.bx); #elif (DOSX & POWERPAK) UNFINISED(); #elif (DOSX == 0) /* real-mode */ union REGS reg; struct SREGS sreg; reg.x.dx = FP_OFF (_country_info); sreg.ds = FP_SEG (_country_info); reg.x.ax = 0x3800; int86x (0x21, ®, ®, &sreg); if (reg.x.cflag) return (0); return (reg.x.bx); #else #error Unsupported target #endif } return (0); }