c++.dos.32-bits - Function addressing in dosX Q.
- E. Trelmar (51/51) Jun 17 2002 I'm having a problem correctly accessing linear memory (I think) in pass...
- Jan Knepper (73/124) Jun 17 2002 Here, some functions I developed years ago to access 'base' memory from ...
- E. Trelmar (5/8) Jun 17 2002 (Code segment removed for space considerations)
- Jan Knepper (5/14) Jun 17 2002 Sorry, I didn't read your message to well obviously. I thought you have ...
- roland (16/71) Jun 17 2002 To trap an interrupt i use to ... use int_intercept / int_restore.
- E. Trelmar (3/3) Jun 21 2002 Thanks for the suggestion roland, the int_intercept/int_restore worked f...
- Heinz Saathoff (9/16) Jun 17 2002 Without answering to the rest (eg. callback from real-mode to protected
I'm having a problem correctly accessing linear memory (I think) in passing segments and offsets to the modified 21h, subfunction 25h series of dos commands, causing a general protection fault from an illegal segment. I'm not too familiar with 32 bit coding, and was wondering what mistake I'm making? If any other bits of code are needed, please tell me and I'll post. Hopefully the code below I have posted isn't too long yet contains everything: static void kbdisr(); void keyboardx::kbdisr() { _disable(); callback(); _enable(); } static void (*oldisr)(); keyboardx::keyboardx() { static void (*previous_isr)(); union _REGS inregs, outregs; struct _SREGS segregs; byte17 = (char *)_x386_zero_base_ptr + 0x00400017; byte97 = (char *)_x386_zero_base_ptr + 0x00400097; _disable(); outp(KEY_BUFFER, 0xEE); if (await_status(0xEE)) keyboard_controller = 8042; else keyboard_controller = 8048; _segread(&segregs); inregs.x.ax = 0x2502; inregs.h.cl = KEYBOARD_INT; intdosx(&inregs, &outregs, &segregs); previous_isr = (void *)(segregs.es + outregs.e.ebx); if (previous_isr != &kbdisr) { oldisr = previous_isr; callback = buffercall; // External keyboard handler function _segread(&segregs); inregs.x.ax = 0x2504; inregs.h.cl = KEYBOARD_INT; inregs.e.edx = 0; /* I put no offset for the address */ segregs.ds = (long)&kbdisr; /* And used only the function's address (The same code is generated with or without the memory offset operand &) */ intdosx(&inregs, &outregs, &segregs); /* Interrupt 0Dh (Hard Disk Access), General Protection Fault (possible illegal segment) on line below*/ } rprs = MAXBUF - 1; // Buffer index for keyboard _enable(); cps_lck = *byte97 & 4; nm_lck = *byte97 & 2; scrll_lck = *byte97 & 1; }
Jun 17 2002
Here, some functions I developed years ago to access 'base' memory from 'extended' memory in DOSX mode. I used these to use the Btrieve DOS engine from a DOSX program. static void _x386_memcpy_ff ( void *, void _far *, size_t ); static void _x386_memcpy_tf ( void _far *, void *, size_t ); static void _x386_memset_f ( void _far *, int, size_t ); [snip] /* * Now make a protected mode pointer to the allocated real mode memory. * Clear the real mode memory and initialize it with the necessary stuff. */ rmidb = ( RMIDB _far * ) _x386_mk_protected_ptr ( abs_addr ); _x386_memset_f ( rmidb, 0, sizeof ( RMIDB ) ); rmidb -> bp.DataBufP = ( long ) ( ( ( long ) DOSBuffSeg << 16 ) + offsetof ( RMIDB, db ) ); rmidb -> bp.PosBlockP = ( long ) ( ( ( long ) DOSBuffSeg << 16 ) + offsetof ( RMIDB, pos ) + 38 ); rmidb -> bp.FCBBuffP = ( long ) ( ( ( long ) DOSBuffSeg << 16 ) + offsetof ( RMIDB, pos ) ); rmidb -> bp.KeyBufP = ( long ) ( ( ( long ) DOSBuffSeg << 16 ) + offsetof ( RMIDB, kb ) ); rmidb -> bp.bswP = ( long ) ( ( ( long ) DOSBuffSeg << 16 ) + offsetof ( RMIDB, bsw ) ); rmidb -> bp.KeyLen = KEYBUF; rmidb -> bp.XFaceID = VARIABLE_ID; [snip] /* * Copy all the parameters to the Real Mode memory area. */ rmidb -> bp.OpCode = operation; rmidb -> bp.BufLen = *dataLength; rmidb -> bp.KeyNum = ( BTI_BYTE ) keyNumber; _x386_memcpy_tf ( rmidb -> db , dataBuffer, *dataLength ); _x386_memcpy_tf ( rmidb -> kb , keyBuffer , KEYBUF ); _x386_memcpy_tf ( rmidb -> pos, posBlock , SZPOS ); /* * Make call to the Btrieve Record Manager. * Btrieve parameter block is expected in DS:DX. */ sregs.ds = DOSBuffSeg; regs.x.dx = 0; int86x_real ( BTR_INTRPT, ®s, ®s, &sregs ); /* * Now copy everything back to the application buffers. */ *dataLength = rmidb -> bp.BufLen; _x386_memcpy_ff ( dataBuffer, rmidb -> db , *dataLength ); _x386_memcpy_ff ( keyBuffer , rmidb -> kb , KEYBUF ); _x386_memcpy_ff ( posBlock , rmidb -> pos, SZPOS ); [snip] _x386_free_protected_ptr ( rmidb ); [snip] static void _x386_memcpy_ff ( void *to, void _far *from, size_t size ) { unsigned char *_to = to; unsigned char _far *_from = from; for ( size_t i = 0 ; i < size ; i++ ) *_to++ = *_from++; } static void _x386_memcpy_tf ( void _far *to, void *from, size_t size ) { unsigned char _far *_to = to; unsigned char *_from = from; for ( size_t i = 0 ; i < size ; i++ ) *_to++ = *_from++; } static void _x386_memset_f ( void _far *to, int b, size_t size ) { unsigned char _far *_to = to; for ( size_t i = 0 ; i < size ; i++ ) *_to++ = b; } "E. Trelmar" wrote:I'm having a problem correctly accessing linear memory (I think) in passing segments and offsets to the modified 21h, subfunction 25h series of dos commands, causing a general protection fault from an illegal segment. I'm not too familiar with 32 bit coding, and was wondering what mistake I'm making? If any other bits of code are needed, please tell me and I'll post. Hopefully the code below I have posted isn't too long yet contains everything: static void kbdisr(); void keyboardx::kbdisr() { _disable(); callback(); _enable(); } static void (*oldisr)(); keyboardx::keyboardx() { static void (*previous_isr)(); union _REGS inregs, outregs; struct _SREGS segregs; byte17 = (char *)_x386_zero_base_ptr + 0x00400017; byte97 = (char *)_x386_zero_base_ptr + 0x00400097; _disable(); outp(KEY_BUFFER, 0xEE); if (await_status(0xEE)) keyboard_controller = 8042; else keyboard_controller = 8048; _segread(&segregs); inregs.x.ax = 0x2502; inregs.h.cl = KEYBOARD_INT; intdosx(&inregs, &outregs, &segregs); previous_isr = (void *)(segregs.es + outregs.e.ebx); if (previous_isr != &kbdisr) { oldisr = previous_isr; callback = buffercall; // External keyboard handler function _segread(&segregs); inregs.x.ax = 0x2504; inregs.h.cl = KEYBOARD_INT; inregs.e.edx = 0; /* I put no offset for the address */ segregs.ds = (long)&kbdisr; /* And used only the function's address (The same code is generated with or without the memory offset operand &) */ intdosx(&inregs, &outregs, &segregs); /* Interrupt 0Dh (Hard Disk Access), General Protection Fault (possible illegal segment) on line below*/ } rprs = MAXBUF - 1; // Buffer index for keyboard _enable(); cps_lck = *byte97 & 4; nm_lck = *byte97 & 2; scrll_lck = *byte97 & 1; }
Jun 17 2002
In article <3D0E1FFC.3ECEE7AE smartsoft.cc>, Jan Knepper says...Here, some functions I developed years ago to access 'base' memory from 'extended' memory in DOSX mode. I used these to use the Btrieve DOS engine from a DOSX program.(Code segment removed for space considerations) I'm a bit confused, how will accessing base memory with far pointers help me with my problem in 32 bit coding when trying to pass a protected mode address to the 32 bit version of int 21h, subfunction 25h? Could you possibly elucidate?
Jun 17 2002
Sorry, I didn't read your message to well obviously. I thought you have problem accessing base memory. Roland might be able to help you with what you want to do. (If he has the time). Jan "E. Trelmar" wrote:In article <3D0E1FFC.3ECEE7AE smartsoft.cc>, Jan Knepper says...Here, some functions I developed years ago to access 'base' memory from 'extended' memory in DOSX mode. I used these to use the Btrieve DOS engine from a DOSX program.(Code segment removed for space considerations) I'm a bit confused, how will accessing base memory with far pointers help me with my problem in 32 bit coding when trying to pass a protected mode address to the 32 bit version of int 21h, subfunction 25h? Could you possibly elucidate?
Jun 17 2002
"E. Trelmar" a écrit :I'm having a problem correctly accessing linear memory (I think) in passing segments and offsets to the modified 21h, subfunction 25h series of dos commands, causing a general protection fault from an illegal segment. I'm not too familiar with 32 bit coding, and was wondering what mistake I'm making? If any other bits of code are needed, please tell me and I'll post.To trap an interrupt i use to ... use int_intercept / int_restore. It's fast and works fine with all interrupt i trapped .. except keyboard interrupt (9) ! Too bad. I don't know why. I didn't try again since a while. So you may try using int_intercept / int_restore functions. If it works for you, please let me know. Good luck dealing with 8042. I use to work with chips, but this one really gives me a lot of trouble. At least with the keyboard chanel. With the PS/2 one it was ok. sorry, can't help more ciao rolandHopefully the code below I have posted isn't too long yet contains everything: static void kbdisr(); void keyboardx::kbdisr() { _disable(); callback(); _enable(); } static void (*oldisr)(); keyboardx::keyboardx() { static void (*previous_isr)(); union _REGS inregs, outregs; struct _SREGS segregs; byte17 = (char *)_x386_zero_base_ptr + 0x00400017; byte97 = (char *)_x386_zero_base_ptr + 0x00400097; _disable(); outp(KEY_BUFFER, 0xEE); if (await_status(0xEE)) keyboard_controller = 8042; else keyboard_controller = 8048; _segread(&segregs); inregs.x.ax = 0x2502; inregs.h.cl = KEYBOARD_INT; intdosx(&inregs, &outregs, &segregs); previous_isr = (void *)(segregs.es + outregs.e.ebx); if (previous_isr != &kbdisr) { oldisr = previous_isr; callback = buffercall; // External keyboard handler function _segread(&segregs); inregs.x.ax = 0x2504; inregs.h.cl = KEYBOARD_INT; inregs.e.edx = 0; /* I put no offset for the address */ segregs.ds = (long)&kbdisr; /* And used only the function's address (The same code is generated with or without the memory offset operand &) */ intdosx(&inregs, &outregs, &segregs); /* Interrupt 0Dh (Hard Disk Access), General Protection Fault (possible illegal segment) on line below*/ } rprs = MAXBUF - 1; // Buffer index for keyboard _enable(); cps_lck = *byte97 & 4; nm_lck = *byte97 & 2; scrll_lck = *byte97 & 1; }
Jun 17 2002
Thanks for the suggestion roland, the int_intercept/int_restore worked fine for keyboard interrupt(0x9). Also, to Heinz Saatho, thanks for the side comment about the byte addressing, almost forgot about that.
Jun 21 2002
E. Trelmar schrieb...keyboardx::keyboardx() { static void (*previous_isr)(); union _REGS inregs, outregs; struct _SREGS segregs; byte17 = (char *)_x386_zero_base_ptr + 0x00400017; byte97 = (char *)_x386_zero_base_ptr + 0x00400097;Without answering to the rest (eg. callback from real-mode to protected mode the above address calculation must be changed to byte17 = (char *)_x386_zero_base_ptr + 0x417; byte97 = (char *)_x386_zero_base_ptr + 0x497; to form a linear address to the bios area. Remember that the notation seg:ofs in real mode forms the address (seg<<4)+ofs Regards, Heinz
Jun 17 2002