Reply 100 of 406, by Baron von Riedesel
crazii wrote on 2023-02-06, 03:05:That's cool! is it possible detect & switch to the module at runtime (support QEMM & the module both)? I was thinking about support different EMMs but not yet starting that. Sine this module almost have the same API like QEMM so I guess only tiny portion need to be adjusted, like detection/entry point and such.
Yes, it's dynamic. The adaption ( in qemm.c, function QEMM_GetVersion() ) is a bit hackish, though, because a real INT 2F has to be executed, not a simulated one. This can surely be improved by someone better aquainted with DJGPP peculiarities
unsigned int result = _dos_open("QEMM386$", O_RDONLY, &fd);// if(result != 0)// return 0;uint32_t entryfar = 0;//ioctl - read from character device control channelDPMI_REG r = {0};if ( result == 0 ) {int count = ioctl(fd, DOS_RCVDATA, 4, &entryfar);_dos_close(fd);if(count != 4)return 0;r.w.cs = entryfar>>16;r.w.ip = entryfar&0xFFFF;} else {/* getting the entry point of QPIEMU is non-trivial in protected-mode, since* the int 2Fh must be executed as interrupt ( not just "simulated" ). Here* a small ( 3 bytes ) helper proc is constructed on the fly, at 0040:00D0,* which is the INT 2Fh, followed by an RETF.*/asm("push ds \n\t""push $0x40 \n\t""pop ds \n\t""mov $0xd0, bx \n\t""mov $0xcb2fcd, (bx) \n\t""pop ds \n\t");r.w.ax = 0x1684;r.w.bx = 0x4354;r.w.sp = 0; r.w.ss = 0;r.w.cs = 0x40;r.w.ip = 0xd0;if( DPMI_CallRealModeRETF( &r) != 0 || (r.w.ax & 0xff))return 0;r.w.ip = r.w.di;r.w.cs = r.w.es;}r.h.ah = 0x03;QEMM_EntryIP = r.w.ip;QEMM_EntryCS = r.w.cs;