Source file: /~heha/hs/dos/kg.zip/KG.ASM

	include	prolog.asm
CapsLockBit EQU 40h    ;im Tastatur-Status-Register

;-----------------------------------------------------------------
;Makros für Übersetzungstabellen.
;-----------------------------------------------------------------

;Tasten-Austausch-Tabellen
;Grundsätzlicher Aufbau: Scancode,NeuerAsciiCode
macro Primary	;Keine der 3 "Shift"tasten
Key 29h,'^'
Key 0Ch,'ß'
Key 0Dh,"'"
Key 2Bh,'#'
Key 1Bh,'+'
Key 35h,'-'
Key 56h,"<"
ENDM

macro Shift	;mit SHIFT
Key 29h,'°'
Key 03h,'"'
Key 04h,''
Key 07h,'&'
Key 08h,'/'
Key 09h,'('
Key 0Ah,')'
Key 0Bh,'='
Key 0Ch,'?'
Key 0Dh,'`'
Key 2Bh,''''
Key 1Bh,'*'
Key 33h,';'
Key 34h,':'
Key 35h,'_'
Key 56h,'>'
ENDM

macro Ctrl	;mit CTRL
Key 2Ch,19h ;Ctrl-Y (darf bei deutschem ROM-BIOS entfernt werden)
Key 15h,1Ah ;Ctrl-Z (darf bei deutschem ROM-BIOS entfernt werden)
Key 0ch,28	;Norton
ENDM

macro Alt
;Key 08h,'┤'
ENDM

macro CtrlAlt
Key 1Eh,'á'
Key 12h,'é'
Key 17h,'í'
Key 18h,'ó'
Key 16h,'ú'
Key 03h,'²'
Key 04h,'ⁿ'
Key 10h,'@'
Key 08h,'{'
Key 09h,'['
Key 0Ah,']'
Key 0Bh,'}'
Key 0Ch,'\'
Key 1Bh,'~'
Key 56h '|'
ENDM

macro ShiftAlt
Key 1Eh,'à'
Key 12h,'è'
Key 17h,'ì'
Key 18h,'ò'
Key 16h,'ù'
Key 03h,'½' ;Shift-Alt-2
Key 05h,'¼' ;Shift-Alt-4
ENDM

macro CtrlShift
Key 2Ch,19h ;Ctrl-Shift-Y wie Ctrl-Y
Key 15h,1Ah ;Ctrl-Shift-Z wie Ctrl-Z
Key 1Eh,'α' ;Ctrl-Shift-A
Key 30h,'ß' ;Ctrl-Shift-B
Key 2Eh,'τ' ;Ctrl-Shift-C
Key 22h,'Γ' ;Ctrl-Shift-G
Key 20h,'δ' ;Ctrl-Shift-D
Key 19h,'π' ;Ctrl-Shift-P
Key 1Fh,'σ' ;Ctrl-Shift-S
Key 32h,'µ' ;Ctrl-Shift-M
Key 18h,'Ω' ;Ctrl-Shift-O
Key 21h,'Φ' ;Ctrl-Shift-F
Key 12h,'ε' ;Ctrl-Shift-E
Key 14h,'Θ' ;Ctrl-Shift-T
Key 10h,'√' ;Ctrl-Shift-Q
ENDM

macro CtrlShiftAlt
Key 1Eh,'â'
Key 12h,'ê'
Key 17h,'î'
Key 18h,'ô'
Key 16h,'û'
ENDM


;die Upcase-Austausch-Tabelle!
macro LowerCase
Key 28h,'ä'
Key 27h,'ö'
Key 1Ah,'ü'
Key 2Ch,'y'
Key 15h,'z'
ENDM

macro UpperCase
Key 28h,'Ä'
Key 27h,'Ö'
Key 1Ah,'Ü'
Key 2Ch,'Y'
Key 15h,'Z'
ENDM

;die Scancode-Austausch-Tabelle!
;Aufbau hier: AlterScancode,NeuerScancode
macro ScanXchg
Key 2Ch,15h	;Z->Y
Key 15h,2Ch	;Y->Z
Key 79h,03h	;
;Key 52h,52h	;Insert; Ziel: Autorepeat
Key 0ch,2bh	;Ziel: Norton Commander Ctrl\
ENDM


;-----------------------------------------------------------------
IFDEF ConfigSys
;-----------------------------------------------------------------
	org	0
DevHdr	tDevHdr	<,,ofs Strategy,ofs Install,>
Ignore:	RETF

;-----------------------------------------------------------------
ELSE ;IFNDEF ConfigSys
;-----------------------------------------------------------------

jmp	Install

;-----------------------------------------------------------------
ENDIF
;-----------------------------------------------------------------

;-----------------------------------------------------------------
;residenter Datenbereich
;-----------------------------------------------------------------

E0Flag          DB 0
		EVEN ;gerade Adresse erzwingen


macro Setup Table
Table&Size=0
macro Key Key,Symbol
DB LOW Symbol,Key
Table&Size=Table&Size+1
ENDM
Table&Addr:
ENDM

		; ────┐
Setup Primary   ;     │
		;     │
LowerCase       ;     ├── CapsLock nicht aktiv
		; ═╗  │   Shift nicht gedrückt
Primary         ;  ║  │
		; ─║──┘
Setup Shift     ;  ╠════ CapsLock aktiv
		; ─║──┐  Shift nicht gedrückt
UpperCase       ;  ║  │
		; ═╝  │
		; ═╗  │
Shift           ;  ║  ├── CapsLock nicht aktiv
		; ─║──┘   Shift gedrückt
Setup Caps      ;  ║
		;  ║
LowerCase       ;  ╠══ CapsLock aktiv
		; ═╝   Shift gedrückt

IRP X,<Ctrl,Alt,CtrlShift,CtrlAlt,ShiftAlt,CtrlShiftAlt,ScanXchg>
Setup X
X
ENDM
;8 Adressen als Tabelle
AddrIndex       DW PrimaryAddr,ShiftAddr
		DW CtrlAddr,CtrlShiftAddr
		DW AltAddr,ShiftAltAddr
		DW CtrlAltAddr,CtrlShiftAltAddr
;8 Längenbytes als Tabelle
SizeIndex       DB PrimarySize,ShiftSize
		DB CtrlSize,CtrlShiftSize
		DB AltSize,ShiftAltSize
		DB CtrlAltSize,CtrlShiftAltSize
;Merkzelle für's E0-Prologbyte

;-----------------------------------------------------------------
;residenter Codebereich
;-----------------------------------------------------------------

proc NewInt09 c far
	push	DS BX AX CX ES DI
	CLD
	LD	es,cs
	MOV	CX,40h		;CH bleibt ab hier 0
	MOV	DS,CX

	XOR	BX,BX		;Tastencode-Scancode-Merker löschen

	TEST	[by 96h],bit 3	;RightAlt gedrückt?
	MOV	AL,bit 2 + bit 3;CtrlAlt vortäuschen
	JNZ	@@1		;ja, Normales Statusflag ignorieren
	MOV	AL,[17h]	;Flags für Shift/Ctrl/Alt/Caps
@@1:	MOV	DI,AX		;retten
	SHR	AL,1		;Rechte Shift-Taste?
	JNC	@@2		;nicht gedrückt.
	OR	AL,1		;Der linken Shift-Taste gleichstellen
@@2:	AND	AX,7		;Nur ALT|CTRL|SHIFT
	TEST	AL,6		;ALT|CTRL gedrückt?

	XCHG	DI,AX		;zum Adressieren nach DI, AX nun Original-Shiftstate
	MOV	CL,[CS:SizeIndex+DI] ;Eine der 8 Größen
	ROL	DI,1		;ROL läßt Z-Flag unberührt!
	MOV	DI,[CS:AddrIndex+DI] ;Eine der 8 Adressen

	JNZ	@@S		;wenn ALT|CTRL gedrückt
	TEST	AL,bit 6	;Caps Lock?
	JZ	@@S		;nö!
	ADD	DI,2*CapsSize   ;Ja, Versatz addieren!

@@S:	IN	AL,60h		;Scancode auslesen
	MOV	AH,AL		;retten
	cmp	al,45h
	jnz	@@NoSw
	test	[by 17h],bit 2	;Tastaturstatus: CTRL gedrückt?
	jz	@@NoSw		;nein
	sub	[wo cs:addy],12*2
	;nächste Codeliste abwärts, ggf. Originalcode
	jnb	@@NoSw		;kein Unterlauf
	mov	[wo cs:addy],12*2*4
@@NoSw:	CMP	[CS:E0Flag],0E0h ;Letztens nur das dusselige E0?
	MOV	[CS:E0Flag],AL	;jetziges Zeichen fürs nächste Mal merken
	JZ	@@c1		;ja, graue Tasten
@@l:	JCXZ	@@c		;Tabellenlänge 0? - Schleife ggf. überspringen
	dec	cl
	MOV	AL,[ES:DI]	;Zeichencode laden
	SCASW			;Scancode gleich? (AL ist logischerweise IMMER gleich)
	jnz	@@l		;wenn ungleich: weiterwurschteln
	MOV	BX,AX		;Tastencode-Scancode-Kombination merken
	jr	@@c
@@c1:	cmp	al,52h		;Graue Insert-Taste
	jnz	@@c
	mov	bh,al		;Neuen Code wegen Autorepeat erzeugen!
@@c:
	MOV	DI,OFFSET ScanXchgAddr
	MOV	CL,ScanXchgSize
@@l2:	jcxz	@@3		;Raus wenn erledigt!
	dec	cl
	MOV	AL,[ES:DI]
	SCASW			;Dieselbe trickreiche Prozedur wie oben
	jnz	@@l2
	MOV	BH,AL		;Neuer Scancode, ggf. ASCII-Code=0
@@3:	MOV	AX,[1Ch]	;Zeiger neuestes Zeichen im Puffer
	PUSHF
	 CALLF
OldInt09 dd	?		;Tastencode abholen & in Puffer schreiben lassen
	XCHG	BX,AX

	CMP	[wo BX],5300h+'.' ;Dezimalpunkt vom Ziffernblock im Puffer?
	JNZ	@@5		;nö, weiter
	TEST	[by 17h],bit 6	;CapsLock gesetzt?
	JZ	@@5
	MOV	[by BX],','	;Komma liefern bei gedrücktem Capslock!
@@5:
	OR	AX,AX		;Scan-Code oder Zeichen ändern?
	JZ	@@e		;Nein: Exit
	MOV	[BX],AX		;Ja: Zeichen im Puffer ablegen (patchen)
	LEA	AX,[BX+2]	;Ringpuffer-Organisation, trickreich
	CMP	AL,3eh		;und (via AL) speichersparend
	JNZ	@@4
	MOV	AL,1Eh
@@4:	CMP	AX,[1Ah]	;Puffer voll?
	JZ	@@e		;ja, EXIT
	MOV	[1Ch],AX	;neuen Wert eintragen.
@@E:	mov	ax,[bx]		;Scancode
	push	bx
	mov	bx,12*2
@@lop:	sub	bx,2
	jb	@@Nix
	cmp	ax,[cs:bx+scantb]
	jnz	@@lop
	db	81h,0c3h	;add bx,{word}...
addy	dw	0
	mov	ax,[cs:bx+scantb]
@@Nix:	pop	bx
	mov	[bx],ax		;neuen oder unveränderten Scancode eintragen
	pop	di es cx ax bx DS
	iret
endp

scantb	dw 4737h,4838h,4939h
	dw 4b34h,4c35h,4d36h
	dw 4f31h,5032h,5133h
	dw 532ch,532eh,5230h
	dw 0d6h,0d2h,0b7h,0c7h,0d7h,0b6h;┌┬┐├┼┤
	dw 0d3h,0d0h,0bdh,0bah,0bah,0c4h;└┴┘││─
	dw 0d5h,0d1h,0b8h,0c6h,0d8h,0b5h;
	dw 0d4h,0cfh,0beh,0b3h,0b3h,0cdh;
	dw 0c9h,0cbh,0bbh,0cch,0ceh,0b9h;
	dw 0c8h,0cah,0bch,0bah,0bah,0cdh;
	dw 0dah,0c2h,0bfh,0c3h,0c5h,0b4h;
	dw 0c0h,0c1h,0d9h,0b3h,0b3h,0c4h;
ResEnd:

RequestPtr      DD ?          ;Zeiger auf Request-Header

;-----------------------------------------------------------------
IFDEF ConfigSys
;-----------------------------------------------------------------

proc Strategy far
	SES	[CS:RequestPtr],BX
	RET
endp

proc Install c far
 uses ax,bx,dx,ds,es
	LD	ds,cs
	DOS	3509h
	SES	[OldInt09],bx
	mov	dx,ofs NewInt09
	DOS	2509h

;Regulären Eintrittspunkt im Device-Header vermerken

	MOV	AX,ofs Ignore	;Weitere Aufrufe ignorieren lassen
	MOV	[DevHdr.pStrat],AX
	MOV	[DevHdr.pIntr],AX
	PRINT	OkMsg

;Treiber-Ende und Status im Request-Block vermerken

	lds	BX,[RequestPtr]	;Das ist NICHT der Device-Header, sondern
				;der Device-Treiber-Request-Block!
	SCS	[bx+14],ofs ResEnd
	MOV	[wo BX+3],300h
	RET
endp

;-----------------------------------------------------------------
ELSE ;IFNDEF ConfigSys
;-----------------------------------------------------------------

Install:
	PRINT	OkMsg
	DOS	3509h
	SES	[OldInt09],bx
	mov	dx,ofs NewInt09
	DOS	2509h
	mov	dx,ofs ResEnd
	int	27h

;-----------------------------------------------------------------
ENDIF
;-----------------------------------------------------------------

OkMsg	db	'KG: Tastaturtreiber geladen...',nl,'$'

	END
Detected encoding: OEM (CP437)1
Wrong umlauts? - Assume file is ANSI (CP1252) encoded