Category : OS/2 Files
Archive   : OS2KBSPD.ZIP
Filename : KBRATE.ASM

 
Output of file : KBRATE.ASM contained in archive : OS2KBSPD.ZIP
NAME KBRATE

.286p

_DATA SEGMENT WORD PUBLIC 'DATA'
_DATA ENDS
STACK SEGMENT PARA STACK 'STACK'
STACK ENDS
_TEXT SEGMENT BYTE PUBLIC 'CODE'
_TEXT ENDS
KBDIO SEGMENT BYTE PUBLIC 'CODE'
KBDIO ENDS
DGROUP GROUP _DATA,STACK


_DATA SEGMENT
ASSUME DS:DGROUP

intro DB "KBRATE -- Set PC-AT keyboard repeat rate [OS/2 Version 1.02]",13,10
DB 10,10,"$"
INTROLEN EQU $-intro-1

invletter DB " Invalid letter for repeat rate",13,10,"$"
INVLETTERLEN EQU $-invletter-1

invnumeral DB " Invalid numeral for delay time",13,10,"$"
INVNUMERALLEN EQU $-invnumeral-1


kbrateusage DB 13,10
DB "Usage: KBRATE xy",13,10
DB " 'x' is a letter A..Z which gives the"
DB "repetition rate in",13,10
DB " characters per second (A = fastest).",13,10
DB 13,10
DB " Some useful values are A = 30, C = 24, E = 20",13,10
DB " I = 15, M = 10, Q = 7.5",13,10,10
DB " 'y' is a numeral 1..4 ehich gives the time delay",13,10
DB " between a key's first depression and the start",13,10
DB " of its repetition, in units of a quarter of a",13,10
DB " second.",13,10
DB 13,10,"$"
KBRATEUSAGELEN EQU $-kbrateusage-1

kbrateset DB " Keyboard rate set",13,10,"$"
KBRATESETLEN EQU $-kbrateset-1

notset DB " I/O error: Keyboard rate not set",13,10,"$"
NOTSETLEN EQU $-notset-1


cmdlineseg DW 0 ; selector for command line
cmdlineoff DW 0 ; offset of command line in segment

saveoffset DW 0000h
savesegment DW 0000h
savebyte DB 00h
savebyte2 DB 00h
savebyte3 DB 00h

_DATA ENDS


STACK SEGMENT
ASSUME SS:STACK
mystack DW 100h DUP (?)
stacktop DW 0000
STACK ENDS


_TEXT SEGMENT
ASSUME CS:_TEXT,DS:DGROUP
; +-------------------------------------------------------------------+
; | Symbols |
; +-------------------------------------------------------------------+


keyboard_cmd equ 064h ; keyboard command register
keyboard_status equ 064h ; same register for status
keyboard_data equ 060h ; port to write data to

kbd_inbuf_full equ 02h ; bit mask for kbd ibf
kbd_outbuf_full equ 01h ; bit mask for kbd obf


std_mode_cmd equ 0ADh ; command for i-s mode
dec_mode_cmd equ 0ACh ; command for DEC mode
kbd_ack equ 0FAH ; acknowledge from keyboard


;
; +-------------------------------------------------------------------------+
; | Variables |
; +-------------------------------------------------------------------------+
;

PRTMSG MACRO msg,msglen
XOR AX,AX ; handle of stdout for OS/2
PUSH AX
MOV AX,msglen ; the length of the message
PUSH AX
MOV AX,OFFSET msg ; the message
PUSH DS
PUSH AX
CALL DOSPUTMESSAGE
ENDM

IFREAL MACRO target
PUSH AX ; create stack space for answer
MOV AX,SP ; prepare pointer to this byte
PUSH SS ; push ptr to this byte SS:AX
PUSH AX
CALL DOSGETMACHINEMODE
POP AX ; adjust stack & get result into AL
CMP AL,00h ; real mode?
JZ target
ENDM

IFPROT MACRO target
PUSH AX ; create stack space for 1 byte
MOV AX,SP ; prepare pointer to this byte
PUSH SS ; push ptr to this byte SS:AX
PUSH AX
CALL DOSGETMACHINEMODE
POP AX ; adjust stack & get result into AL
CMP AL,01h ; prot mode?
JZ target
ENDM


EXTRN DOSPUTMESSAGE:FAR
EXTRN DOSEXIT:FAR
EXTRN DOSGETMACHINEMODE:FAR

main PROC NEAR
; AX:BX points to the command line under OS/2
; AX:0000h is our environment under OS/2
; ES:0080h is length of arguments under DOS
; ES:0081h is start of command line under DOS

MOV WORD PTR cmdlineseg,AX ; save ptr to command line
MOV WORD PTR cmdlineoff,BX ; (even if not under OS/2)

; display our welcome message
PRTMSG intro,INTROLEN

;
;
; In OS/2, the command line is at AX:BX (cmdlineseg:cmdlineoff)
; In DOS, the command line is at ES:0081h (length at ES:0080h)


dosparse: ; parse command line under MS-DOS
CALL NEAR PTR getinit ; set up forÿparsing
; CX now has the # of bytes
OR CX,CX ; JCXZ usage
JNZ dosparse1
JMP usage

dosparse1: CALL NEAR PTR getchar
CMP AL,20h ; is it a space?
JZ dosskipwhite
CMP AL,09h ; is it a ?
JZ dosskipwhite
CMP AL,00h ; null (end of cmd line)?
JNZ doseval ; no: evaluate
JMP usage ; yes: no arguments present

dosskipwhite: LOOP dosparse1
JMP usage

doseval: ; check for a valid letter A..Z (after capitalizing)
AND AL,0DFh
SUB AL,41h ;'A'
CMP AL,19h
JBE goodletter

PRTMSG invletter,INVLETTERLEN ; bad letter
JMP badness

goodletter: MOV BYTE PTR savebyte,AL
CALL NEAR PTR getchar
SUB AL,31h ;'1'
CMP AL,03h ; in 1..4?
JBE goodnumber

PRTMSG invnumeral,INVNUMERALLEN
JMP badness

goodnumber: MOV BYTE PTR savebyte2,AL ; now compute magic #
MOV AL,BYTE PTR savebyte2 ;
MOV CL,05h ;
SHL AL,CL ;
OR AL,BYTE PTR savebyte ;;

PUSH AX ; save the speed
; AL now has the speed byte that we want (also on stack)


; Now that we have our magic number for the keyboard in AL
; and on top of the stack, lets send out the commands!

mov al,0F3h ; set rate command
call FAR PTR send_cmd ;
pop ax ; restore the speed into AX
jc badness2 ;;

call FAR PTR send_cmd ; now send out the speed
jc badness2 ;;

mov al,0F4h ; enable keyboard
call FAR PTR send_cmd ;
jc badness2 ;;

PRTMSG kbrateset,KBRATESETLEN

goodness: ; terminate w/no error
XOR AX,AX
PUSH AX
PUSH AX
CALL DOSEXIT

usage: PRTMSG kbrateusage,KBRATEUSAGELEN
JMP badness

badness2: PRTMSG notset,NOTSETLEN

badness: ; terminate with error
MOV AX,0001h
PUSH AX
PUSH AX
CALL DOSEXIT

main ENDP


; +-------------------------------------------------------------------+
; | getinit - initialize for getting characters from command line. |
; | Set up ES:SI to point to the command line. |
; | Also, skip program name when under OS/2. |
; | CX is set to the length of the command line arguments. |
; +-------------------------------------------------------------------+
getinit PROC NEAR

getinitp: ; protected mode init
MOV AX,WORD PTR cmdlineseg
MOV ES,AX
MOV SI,WORD PTR cmdlineoff

; now ES:SI points to program name (which we must skip)
CMP BYTE PTR ES:[SI],00h ; special case (no args)
JZ giend
giskip: MOV AL,BYTE PTR ES:[SI] ; look at next character
CMP AL,20h ; a space?
JZ giend ; yes: exit
CMP AL,00h ; a separator (or end)?
JZ giend ; yes: exit
INC SI ; no: loop
JMP giskip ;;

giend: SMSW AX ; get machine status word -> AX
TEST AX,0001h ; in protected mode?
JZ skiplsl ; no: skip LSL instruction

MOV AX,ES ; get selector in AX
LSL CX,AX ; get segment limit

;; Special code to ensure last byte is 00h in command line
; PUSH BX
; MOV BX,CX
; MOV BYTE PTR ES:[BX],00h ; make sure last byte is 00h
; POP BX

JMP postlsl

skiplsl: MOV CX,0010h ; lie about # of bytes there

postlsl: SUB CX,SI ; subtract start
SUB CX,0002h ; less null terminators
RET
getinit ENDP


; +-------------------------------------------------------------------+
; | getchar - return the next character in AL at ES:SI. |
; +-------------------------------------------------------------------+
getchar PROC NEAR

MOV AL,BYTE PTR ES:[SI] ; get the byte
INC SI
CMP AL,00h ; arg separator?
JNZ getend ; no: return
MOV AH,BYTE PTR ES:[SI] ; peek at next char
CMP AH,00h ; is next char null?
JZ getend ; yes: return null
MOV AL,20h ; no: return a space
getend: RET

getchar ENDP



_TEXT ENDS


KBDIO SEGMENT
ASSUME CS:KBDIO,DS:DGROUP
send_cmd proc far

mov bx,ax ; save command

xor cx,cx ; wait a long time
cli ; so BIOS can't get in the way
in al,keyboard_data ; clear outbut buffer

wait_kbd: in al,keyboard_status ; read status
test al,kbd_inbuf_full ; is input buffer full?
loopnz wait_kbd ; keep waiting
jcxz timeout ; if timeout
mov al,bl ; get back command
out keyboard_data,al ;

; now, wait for the acknowledge
xor cx,cx ; timeout
wait_ack: in al,keyboard_status ; read status
test al,kbd_outbuf_full
loopz wait_ack ; wait for ACK
jcxz timeout ; timed out
in al,keyboard_data ; read byte
cmp al,kbd_ack ; is it an ACK?
jnz wait_ack ; nope.

sti ; ok to use port now
clc ; no errors
ret

timeout: sti ; ok to use port now
stc ; error waiting for kbd
ret

send_cmd ENDP
KBDIO ENDS

END main



  3 Responses to “Category : OS/2 Files
Archive   : OS2KBSPD.ZIP
Filename : KBRATE.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/