John Coppens wrote:
Did you intend to take this to private e-mail?
On Fri, 30 Nov 2007 12:41:38 -0600
Mike McCarty <Mike.McCarty@xxxxxxxxxxxxx> wrote:
John Coppens wrote:
Hello people.
[snip]
All this is important, because I want to simulate keypresses and the
TSR doesn't seem to work with any CRT using Pascal program.
I don't understand this statement. Do you mean that there is another
TP program which uses the CRT module and which must run with this
TSR, but does not?
Hi Mike. Sorry for all the confusion. It's the TSR that has to generate
the keypresses, and the TSR works fine. Eg. I can call 'debug', send a
dump command, and exit again, all via the TSR.
The sensor logger is the one that seems to be compiled with 'uses CRT' in
Pascal, which means that the executable uses Int16 instead of the DOS
routines to read the keyboard (and to write the screen).
Ah, I see. So, the TSR is stuffing the BIOS TA buffer, but you aren't
able to get it from the *other* program. AIUI the TSR isn't running
because the DOS IDLE interrupts aren't being used. This is, as you say,
because you use the BIOS keyboard interrupts.
I followed the program to be using Int16 for key input, which probably
explains why no Int28 or Int1C calls are made anymore (needed for the
TSR to work)...
I also don't follow this. The Int16 BIOS calls don't disturb the
clock interrupts, AFAIK. I've used them many times.
Yes... The logger calls Int16, which works fine, except that in that case
the TSR stops working, because both 'hooks' to 'stimulate' the TSR (Int
1C and 28) stop working (see below). Note that both 1Ch and 28h are
'voluntary' interrupts, called only when DOS is idle. So while in the
(BIOS's) Int16, DOS won't be able to call them.
Which INT16 services are you using? [grabs old MSDOS programming book]
Service 00H Wait until a characer is ready for input, put into AL
01H Read status, return flag and char if one ready
02H Return keyboard flags
Ok, I guess you're calling service 00H, and it is "hang and wait".
I take issue with your statement that INT 1CH is optional. As I stated
before, it is the system clock interrupt (software level). INT 28 is
DOS_IDLE as you stated. But even if DOS_IDLE is not being called,
INT 1C should be.
I tried to follow where 16h goes to, but, using debug in DOSemu, this
leads to a HLT instruction...
Sounds like the TSR may be trying to guard itself against debug. I wrote
some device drivers 'way back on contract, and the people I worked
for wanted to prevent them from running when debug was being used.
No. It's not the TSR. Run xdosemu, and then debug (no TSR running). The
16h interrupt vector points to F800:682E. At that address is a very
simple routine:
F800:682E FB STI
F800:682F F6C4EF TEST AH,EF
This code looks for an extended keyboard service.
F800:6832 7405 JZ 6839
We get here for all "normal" services, except service 00H.
So, services 00H and 10H wind up here. 00H is read keyboard.
F800:6834 EA16C000F0 JMP F000:C016
F800:6839 9C PUSHF
F800:683A 9A16C000F0 CALL F000:C016
F800:683F 74F8 JZ 6839
F800:6841 CF IRET
And at F000:C016 is a HLT. I suspect this is part of the mechanism dosemu
uses to emulate.
Ah. Interesting. Perhaps the HLT instruction is mis-emulated!
It should halt until an interrupt occurs, then exit. It appears
that the hardware clock interrupts are not being passed through
to the emulation level to cause the HLT to exit. As a NASTY work
around, you could patch out the STI instruction. This leaves
you with a window during which the code might hang, due to the
keyboard interrupt arriving just before the HLT. If the clock
interrupt eventually does get passed through, then it would
eventually recover. You could do this in a little program which
runs just before the TSR gets run (and installs itself) during boot.
Hopefully, this area is not in emulated ROM, prohibiting writes.
If it is, then you could copy the entire BIOS INT 16H routine
into ANOTHER TSR which then omits the STI, and revector
to that.
Another possibility is to patch the program using CRT to use
service 01H in a loop until it finds "character ready" and then
use service 00H to read it, which hopefully then doesn't enter
this code. Or put that into another TSR (as above) which emulates
service 00H by using 01H until it gets "ready" and then use
00H to read it and return. This may be the best way, as it has
very little interaction with other programs, and is less "fiddly".
This little TSR could be just a few bytes long, actually. The
code would look like this:
resize memory END_MEM
disable interrupts
save old INT 16H vector
set self as new INT 16H handler
enable interrupts
TSR
handler:
if service is not 00H
jump to old INT 16H vector
loop:
load AH with 01H
push flags to emulate interrupt
call old INT 16H vector
if flag indicates not ready
jmp to loop
load AH with 00H
push flags to emulate interrupt
call old INT 16H vector
IRET
END_MEM:
Another possibility is to patch the program using CRT to use
the corresponding MSDOS call INT 21H service 08H to read a
character w/o echo. This opens you up to ^C and ^BREAK messing
you up, however. Do you already trap those? You'd need an
INT 23H handler.
[...]
Hope this clears it up...
I think I've got a better handle. This looks like an oversight
in dosemu which causes an interaction when used with the INT 16H
BIOS keyboard interrupt service.
http://www.ctyme.com/intr/int-16.htm
Your best bet may be the little TSR I described above.
Mike
--
p="p=%c%s%c;main(){printf(p,34,p,34);}";main(){printf(p,34,p,34);}
Oppose globalization and One World Governments like the UN.
This message made from 100% recycled bits.
You have found the bank of Larn.
I can explain it for you, but I can't understand it for you.
I speak only for myself, and I am unanimous in that!
-
To unsubscribe from this list: send the line "unsubscribe linux-msdos" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html