I am writing a programm for controlling a motor (using LPT1) that moves 47 um/clock (0.000047 meters per clock). I move the motor in a direction according to a key pressed (read key with bios-interrupt 21h with function 1) and repeate asking if a key was pressed until ESC is pressed. My only problem is that the programm is too slow or is it the keyboard ? (i don't know!), but the motor only moves about 30 millimeters in a sec.

How can i speed it up?


Thanks.

Mike
Posted on 2001-11-21 15:04:06 by ritter
ritter,

I confess to being very rusty in DOS coding but I think the typematic rate is the culprit here. What I would be inclined to do is only use the keyboard to "switch" the proces on and control what you point out LPT1 yourself. You can get much higher data output rates from a printer port than the keyboard will send by writing it yourself.

Most of the modern printer ports will handle data both ways at speeds of over 1 meg/sec so you should not have any real speed problems there.

Regards,

hutch@movsd.com
Posted on 2001-11-21 16:52:20 by hutch--
indeed.

Make a variable that holds the data corrisponding to the current direction, {0,1,2....} . As it loops get it to write that to the port every time. Only check for a key every couple cycles, then overight the variable with any new data. Say they press ESC, write null.
Posted on 2001-11-21 18:49:59 by -T-
Could you please show us your program?, maybe that will help a little more. ;)
Posted on 2001-11-21 19:14:21 by CodeLover
Some BIOSes have a setting to control the typematic rate. :)
Posted on 2001-11-21 20:10:50 by S/390
Almost all BIOSes have. If not, you can set it yourself. The problem
is, there's only a few possible settings. I think the fastest you can
get is 250ms delay, 30chars/sec. Now, if you really want fast keyboard
handling, trap IRQ1 (the keyboard IRQ... interrupt 9 in DOS mode).
You get the key pressed by "in al, 60h" (note, this is scancode and
not ascii!). After you have the key, you must perform the following
sequence:



; reset keyboard, get ready for next key
in al,61h
mov ah,al
or al,80h
out 61h,al
mov al,ah
out 61h,al
; send "end of interrupt" hardware signal to the CPU
cli
mov al,020h
out 020h,al


I've seen simpler routines, but there's some cases where they fail.
Looking at the code fragment, I'm confused why I cli and don't sti.
It's been five years since I wrote this code, and 3-4 years since I
used it. But I don't recall touching the code afterwards, so it should
work.

Now, if you want to use this code AND have the bios/dos readkey
stuff work, you will need to call the old interrupt vector (and then
you should neither reset keyboard nor send EOI).
Posted on 2001-11-21 21:04:08 by f0dder
Thanks for the tips. I tried to speed it up using the typematic rate (see code), it wasn't so successful.

Here is the code (someone asked for it):

Adresse Macro
mov ax, 40h
mov ds, ax
mov bx, 8h
mov dx,
endm

Speed Macro
mov dx, 21H
mov al, 02H
out dx, al
mov dx, 60H
mov al, 0F3H
out dx, al
mov dx, 60H
mov al, 00000000B
out dx, al
mov dx, 21H
mov al, 00H
out dx, al
endm


Move Macro x1,x2,x3,x4

Adresse
mov al, x1
out dx, al
mov al, x2
out dx, al

Adresse
inc dx
in al, dx
xor al, 80H
and al, 10110000B
cmp al, x3
je x4
endm


Speed

in_loop:

mov ah, 06h
int 21h

cmp al, '6'
je x_plus

cmp al, '4'
je x_minus

cmp al, '8'
je y_plus

cmp al, '2'
je y_minus

cmp al, '+'
je z_plus

cmp al, '-'
je z_minus

cmp al, 27
je b2d


x_plus:
Move 00101011B, 00101001B, 20H, xep
jmp in_loop

x_minus:
Move 00101010B, 00101000B, 20H, xem
jmp in_loop

y_plus:
Move 00101110B, 00100110B, 90H, yep
jmp in_loop

y_minus:
Move 00101010B, 00100010B, 90H, yem
jmp in_loop

z_plus:
Move 00111010B, 00011010B, 0A0H, zep
jmp in_loop

z_minus:
Move 00101010B, 00001010B, 0A0H, zem
jmp in_loop
Posted on 2001-11-22 08:24:49 by ritter