;Makrorecorder für Tastatureingaben
;Tastaturmakro-Datei mit Klartext, mit beliebigem Whitespace und speziellem
;Operator für ClearBuf-Umschiffung
;Bei definiertem Symbol NERV (Shareware-Nervrequester) erfolgt zu Beginn
;und beim Ende der Lernphase ein Nervrequest (Vorbild AMISETUP).
MaxKeys equ 1000 ;Nur ≤ 32767 zulässig!!
MaxWait equ 100h ;Vorgabe
scrkw equ 372ch ;Scramble-Kennung
;switches-Bitbelegung
;0 Record /r
;1
;2
;3
;4
;5 Show mit Hex
;6 Show-Bit /s
;7
;8 Makrodateiname abgeparst
;9 Direkte Programmausführung /x
;10 Programmdateiname abgeparst (?)
;11 Video-Check /v
;12 Tastatur-Unterbrechung AUS /t
;13 Übersetzungs-Modus /t
;14 Binär-Modus /b
;15 Gescrambled /bx
DKEY macro str,hi,lo ;Definiere Tastencode, 3 Parameter
ifb <lo> ;Wenn kein "LO" definiert...
db '&str'
else
db lo
endif
db hi,'&str',0
endm
include prolog.asm
include "strings.asm"
call trans
call setvecs
mov sp,100h
ResizeM
mov bx,ofs PBlock
DOS 4b00h
xchg bx,ax
mov cx,cs
mov ss,cx
mov sp,100h
pushf
lds dx,[cs:OldInt16]
DOS 2516h
mov ds,cx
popf
jnc noerr
mov dx,ofs errmsg
wrerr: push dx
PRINT err$
mov al,bl
call ahex
pop dx
DOS 9
jr wrdone
noerr: test [switches],1
jz wrdone
call runovl
mov dx,ofs ovlmsg
mov bl,al
jc wrerr
wrdone:
xchg al,bl
DOS 4ch ;Das Ende vom Lied der Echse
err$:
db 'MREC: Fehler $'
errmsg:
db ' beim Ausführen des Hauptprogramms!',nl,'$'
ovlmsg:
db ' beim Laden des Dekodier-Overlays (MREC NIEMALS lighten)!',nl,'$'
readwo: ;read a word!, CY=1: Puffer abgerasselt! (leer)
;PE: Bit 0(ah)=1: nur Tastaturstatus
;PA: AX: Tastencode
; CY=1: Puffer leer
;VR: AX,F
push si
mov si,[cs:BufPtr]
cmp si,[cs:BufFst] ;SI noch kleiner als Füllstand?
cmc
jc rw1 ;nein: Puffer ausgekuddelt
test ah,1
segcs lodsw
jnz rw1
mov [cs:BufPtr],si
rw1: pop si
ret
writewo:;write a word! (CY=1: Puffer voll)
push si
mov si,[cs:BufPtr]
cmp si,[cs:BufFst] ;hier: Pufferende
cmc
jc ww1
mov [cs:si],ax
add [cs:BufPtr],2 ;erhöhen
ww1: pop si
ret
NewInt16:
pushf
mov [cs:axstore],ax
test [cs:switches],1 ;Play?
jnz NoEmulP
cmp ah,10h
jz rwo
or ah,ah
jz rwo
cmp ah,11h
jz stat
cmp ah,1
jnz NoEmulP
stat:
call readwo
jc NoEmulP ;Puffer leer, Umschalten normal KBD
push ax
mov ax,[cs:kpCount]
inc ax
cmp [cs:kpCmax],ax ;Wenn kpCmax=65535 dann IMMER
;readkey=false!!! (Verklemmung möglich)
jnc stat1
mov ax,0 ;Rücksetzen
stat1: mov [cs:kpCount],ax
pop ax
jc em2 ;Größer? -> Code emulieren
test [cs:switches],800h
jz em21 ;abwechselnd Code und kein Code!
push ax
call VChk
xchg [cs:vchks],ax
cmp [cs:vchks],ax
pop ax
jz em21
mov [cs:kpCount],0 ;Von vorn warten!
jr em21
rwo:
call readwo
jc NoEmulP
mov [cs:kpCount],0
jr em3 ;raus mit Emulation
NoEmulP:
popf
mov ax,[cs:axstore]
pushf
CALLF
OldInt16 dd ? ;Original-ISR
pushf
test [cs:switches],1 ;Record?
jz NoRec
cmp [by cs:axstore+1],0
jz recit
cmp [by cs:axstore+1],10h
jnz norec
recit: call WriteWo ;Abspeichern
NoRec: popf
sti
retf 2
em21: ;wenn keypressed false liefern soll
;Ausbruchmöglichkeit via Tasten-Hit
test [cs:switches],1000h
jnz em22 ;nie abbrechen!
push ax ;der Code aus dem Puffer
call kread
pop ax
jnz em2 ;Tastencode durchlassen
em22: xor ax,ax
em2: ;Flag entsprechend AX pfuschen
and ax,ax ;Null?
jnz em4
mov ax,[cs:axstore] ;restaurieren!
em4:
call dummy
sti
retf 2
em3: popf
iret
dummy: ret 2
_AXHX ;AX Hexausgabe!
kread:
mov ah,1
pushf
call [cs:OldInt16]
jz kr1
mov ah,0
pushf
call [cs:OldInt16]
or ax,ax ;Z=0!
kr1: ret ;Z=1: keine Taste gedrückt
runovl: ;Overlay laden und starten
push ds es bx
push cs
pop es
ResizeM MemEnd ;etwas Speicher *mehr* bitte!
;für ein paar Dollar mehr
jc roexi01
mov ds,ax
mov es,[2ch] ;Entwirronment
xor ax,ax
xor di,di
cld
envs1: scasb
jnz envs1
scasb
jnz envs1
inc ax
scasw ;die "1" lesen
stc
jnz roExi ;Fehler bei keiner Eins!
push ds
push es
pop ds
xchg dx,di
DOS 3d00h ;OpenRead
pop ds
roexi01: jc roexi
mov bx,ax ;Handle
xor cx,cx
mov dx,ResEnd-COMentry
DOS 4200h ;MoveFP
jc roexi
mov dx,ofs ResEnd
mov cx,PgmEnd-ResEnd
DOS 3fh ;Reading
jc roexi
cmp ax,cx ;Sind alle Bytes da?
mov al,10h ;Fehler-Code
stc
jne roexi
DOS 3eh ;close
call decodex
ifdef NERV
xnerv equ (' ' XOR '─') ;das Xorbyte zum Verscramblen
VID 0fh
cmp al,7 ;Monochrom?
jz ne1
mov al,3
ne1: VID 0 ;Löschen und Textmodus
mov si,ofs Nerv$
cld
ne2: lodsb
xor al,xnerv
jz ne3
cmp al,9 ;TAB?
jnz ne4
xor bh,bh ;Seite Null
VID 3 ;GetCurs
add dl,8
and dl,not 7
VID 2 ;Extrawurst fürs TAB braten
jr ne2
ne4: VID 0eh ;simple Ausgabe
jr ne2
ne3: DOS 0ch,7 ;ClrKeybrdBuf und Tastaturabfrage
endif
clc ;Kein Fehler melden!
roexi: pop bx es ds
ret
VChk: ;Video-Checksum (Textmode) bilden
;PE: -
;PA: AX: Checksumme
;VR: AX,F
push bx cx si ds
mov ah,0fh
int 10h ;GetVideoMode
mov bx,40h
mov ds,bx
mov bx,0b000h ;Segment Hercules
cmp al,7
mov al,25 ;Zeilenzahl Hercules
jz vc1
mov al,[84h] ;Zeilenzahl EGA/VGA
inc al
mov bx,0b800h ;Segment EGA/VGA
vc1: mov si,[4eh] ;Startoffset
mul ah ;ax:=ah*al
mov cx,ax
mov ds,bx
xor ax,ax
jcxz vc3
vc2: add ax,[si]
add si,2
loop vc2
vc3: pop ds si cx bx
ret
axstore dw ?
switches dw ?
handle dw 1 ;Standardausgabe
vchks dw 0 ;Video-Checksumme zum Zählerhochsetzen
kpcmax dw MaxWait ;Keypressed-Zähler-Maximum
kpcount dw 0 ;KeyPressed-Zähler
PBlock dw 0
ParOfs dw ?
ParSeg dw ?
BufPtr dw ofs KBDBuf ;default: Pufferanfang (lesebereit)
BufFst dw ofs ResEnd ;default: Pufferende
comc$: db 'X:\command.com',0
KBDBuf:
hlp$:
db 'Tastatur-Makrorecorder',nl
db 'MREC {/? /r /x /v /l /nn /t /s /bx} <tastaturmakrodatei> <hauptprogramm>',nl
db '/? Diese Hilfeseite',nl
db '/r Aufnahme erzwingen',nl ;force Recording
db '/x <hauptprogramm> wird ohne Kommandointerpreter gestartet',nl ;eXecute directly
db '/v Veränderungen auf Bildschirm erfassen zum Zählerrücksetzen',nl ;check Video changes
db '/l Tastatur gänzlich sperren; sonst hilft Tastendruck bei Verklemmung',nl ;Lock keyboard
db '/nn (nn=Zahl von 0 bis 65535): Festlegung der keypressed-Wiederholrate',nl
db '/t nur <tastaturmakrodatei> übersetzen, nichts ausführen',nl
db '/b Ausgabeformat binär, /bx: binär gescrambled',nl
db '/s Anzeige aller möglichen Tastenkürzel, /sx mit Hex-Code',nl
db 'Ist die <tastaturmakrodatei> nicht vorhanden, wird Aufnahme gestartet,',nl
db 'sonst Wiedergabe ("Geisterfahrt")',nl,0
org KBDBuf+2*MaxKeys
ResEnd:
;===========================================================================
null$ db 0
keylist: ;gültig für DEUTSCHE Tastatur unter KEYB.COM
;(wieder eine andere gilt unter KEYBSCR.COM)
dkey esc,1,1Bh
dkey 1,2
dkey 2,3
dkey 3,4
dkey 4,5
dkey 5,6
dkey 6,7
dkey 7,8
dkey 8,9
dkey 9,0Ah
dkey 0,0Bh
dkey !ß,0Ch
dkey <''>,0Dh
dkey bksp,0Eh,8
dkey tab,0Fh,9
dkey q,10h
dkey w,11h
dkey e,12h
dkey r,13h
dkey t,14h
dkey z,15h
dkey u,16h
dkey i,17h
dkey o,18h
dkey p,19h
dkey !ü,1Ah
dkey !+,1Bh
dkey enter,1ch,0dh
dkey et,1Ch,0Dh
dkey a,1Eh
dkey s,1Fh
dkey d,20h
dkey f,21h
dkey g,22h
dkey h,23h
dkey j,24h
dkey k,25h
dkey l,26h
dkey !ö,27h
dkey !ä,28h
dkey #,29h
dkey !<,2Bh
dkey y,2Ch
dkey x,2Dh
dkey c,2Eh
dkey v,2Fh
dkey b,30h
dkey n,31h
dkey m,32h
dkey !,,33h ;Literales Komma!
dkey .,34h
dkey -,35h
dkey spc,39h,' '
dkey f1,3Bh,0
dkey f2,3Ch,0
dkey f3,3Dh,0
dkey f4,3Eh,0
dkey f5,3Fh,0
dkey f6,40h,0
dkey f7,41h,0
dkey f8,42h,0
dkey f9,43h,0
dkey f10,44h,0
dkey f11,85h,0
dkey f12,86h,0
dkey num*,37h,'*'
dkey num-,4Ah,'-'
dkey num+,4Eh,'+'
dkey numet,0E0h,0Dh
dkey num/,0E0h,'/'
dkey home,47h,0
dkey cuu,48h,0
dkey pgup,49h,0
dkey cul,4Bh,0
dkey cur,4Dh,0
dkey end,4Fh,0
dkey cud,50h,0
dkey pgdn,51h,0
dkey ins,52h,0
dkey del,53h,0
dkey {,7Eh
dkey [,7Fh
dkey ],80h
dkey },81h
dkey \,82h
dkey @,10h
dkey ~,1Bh
dkey |,2Bh
dkey !µ,32h
;ab hier mit SHIFT
dkey ESC,1,1Bh
dkey !!,2
dkey !",3
dkey !,4
dkey !$,5
dkey !%,6
dkey !&,7
dkey !/,8
dkey (,9
dkey ),0Ah
dkey =,0Bh
dkey ?,0Ch
dkey BKSP,0Eh,8
dkey TAB,0Fh,0
dkey Q,10h
dkey W,11h
dkey E,12h
dkey R,13h
dkey T,14h
dkey Z,15h
dkey U,16h
dkey I,17h
dkey O,18h
dkey P,19h
dkey !Ü,1Ah
dkey *,1Bh
dkey ENTER,1ch,0dh
dkey ET,1Ch,0Dh
dkey A,1Eh
dkey S,1Fh
dkey D,20h
dkey F,21h
dkey G,22h
dkey H,23h
dkey J,24h
dkey K,25h
dkey L,26h
dkey !Ö,27h
dkey !Ä,28h
dkey <''>,29h
dkey !>,2Bh
dkey Y,2Ch
dkey X,2Dh
dkey C,2Eh
dkey V,2Fh
dkey B,30h
dkey N,31h
dkey M,32h
dkey !;,33h
dkey !:,34h
dkey _,35h
dkey SPC,39,' '
dkey F1,54h,0
dkey F2,55h,0
dkey F3,56h,0
dkey F4,57h,0
dkey F5,58h,0
dkey F6,59h,0
dkey F7,5Ah,0
dkey F8,5Bh,0
dkey F9,5Ch,0
dkey F10,5Dh,0
dkey F11,87h,0
dkey F12,88h,0
dkey NUM7,47h,37h
dkey NUM8,48h,38h
dkey NUM9,49h,39h
dkey NUM-,4Ah,2Dh
dkey NUM4,4Bh,34h
dkey NUM5,4Ch,35h
dkey NUM6,4Dh,36h
dkey NUM+,4Eh,2Bh
dkey NUM1,4Fh,31h
dkey NUM2,50h,32h
dkey NUM3,51h,33h
dkey NUM0,52h,30h
dkey NUM.,53h,2Eh
dkey NUMET,1Ch,0Dh
dkey HOME,47h,0
dkey CUU,48h,0
dkey PGUP,49h,0
dkey PGDN,4Bh,0
dkey CUR,4Dh,0
dkey END,4Fh,0
dkey CUD,50h,0
dkey PGDN,51h,0
dkey INS,52h,0
dkey DEL,53h,0
dw 0
;Alles ab hier mit Control:
ctrl$ db 'ctrl+',0
keylistc:
dkey bksp,0Eh,7Fh
dkey tab,94h,0
dkey q,10h,11h
dkey w,11h,17h
dkey e,12h,5
dkey r,13h,12h
dkey t,14h,14h
dkey z,15h,1ah
dkey u,16h,15h
dkey i,17h,9
dkey o,18h,0Fh
dkey p,19h,10h
dkey !ü,1Ah,1Bh
dkey +,1Bh,1Dh
dkey et,1Ch,0Ah
dkey enter,1ch,0ah
dkey a,1Eh,1
dkey s,1Fh,13h
dkey d,20h,4
dkey f,21h,6
dkey g,22h,7
dkey h,23h,8
dkey j,24h,0Ah
dkey k,25h,0Bh
dkey l,26h,0Ch
dkey !<,2Bh,1Ch ;???
dkey y,2Ch,19h
dkey x,2Dh,18h
dkey c,2Eh,3h
dkey v,2Fh,16h
dkey b,30h,2h
dkey n,31h,0Eh
dkey m,32h,0Dh
dkey num*,96h,0
dkey spc,39,' '
dkey f1,5Eh,0
dkey f2,5Fh,0
dkey f3,60h,0
dkey f4,61h,0
dkey f5,62h,0
dkey f6,63h,0
dkey f7,64h,0
dkey f8,65h,0
dkey f9,66h,0
dkey f10,67h,0
dkey f11,89h,0
dkey f12,8Ah,0
dkey numhome,77h,0
dkey numcuu,8Dh,0
dkey numpgup,84h,0
dkey num-,8Eh,0
dkey numcul,73h,0
dkey num5,8Fh,0
dkey numcur,74h,0
dkey num+,90h,0
dkey numend,75h,0
dkey numcud,91h,0
dkey numpgdn,76h,0
dkey numins,92h,0
dkey numdel,93h,0
dkey numet,0E0h,0Ah
dkey num.,95h,0
dkey home,77h,0E0h
dkey cuu,8Dh,0E0h
dkey pgup,84h,0E0h
dkey cul,73h,0E0h
dkey cur,74h,0E0h
dkey end,75h,0E0h
dkey cud,91h,0E0h
dkey pgdn,76h,0E0h
dkey ins,92h,0E0h
dkey del,93h,0E0h
dw 0
;Ab hier alles mit ALT
alt$ db 'alt+',0
keylista:
dkey esc,1,0
dkey 1,78h,0
dkey 2,79h,0
dkey 3,7Ah,0
dkey 4,7Bh,0
dkey 5,7Ch,0
dkey 6,7Dh,0
dkey 7,7Eh,0
dkey 8,7Fh,0
dkey 9,80h,0
dkey 0,81h,0
dkey !ß,82h,0
dkey =,83h,0
dkey bksp,0Eh,0
dkey tab,0A5h,0
dkey q,10h,0
dkey w,11h,0
dkey e,12h,0
dkey r,13h,0
dkey t,14h,0
dkey z,15h,0
dkey u,16h,0
dkey i,17h,0
dkey o,18h,0
dkey p,19h,0
dkey !ü,1Ah,0
dkey +,1Bh,0
dkey et,1Ch,0
dkey enter,1ch,0
dkey a,1Eh,0
dkey s,1Fh,0
dkey d,20h,0
dkey f,21h,0
dkey g,22h,0
dkey h,23h,0
dkey j,24h,0
dkey k,25h,0
dkey l,26h,0
dkey !ö,27h,0
dkey !ä,28h,0
dkey #,29h,0
dkey !<,2Bh,0
dkey y,2Ch,0
dkey x,2Dh,0
dkey c,2Eh,0
dkey v,2Fh,0
dkey b,30h,0
dkey n,31h,0
dkey m,32h,0
dkey !,,33h,0
dkey .,34h,0
dkey -,35h,0
dkey num*,37h,0
dkey spc,39h,' '
dkey f1,68h,0
dkey f2,69h,0
dkey f3,6Ah,0
dkey f4,6Bh,0
dkey f5,6Ch,0
dkey f6,6Dh,0
dkey f7,6Eh,0
dkey f8,6Fh,0
dkey f9,70h,0
dkey f10,71h,0
dkey f11,8Bh,0
dkey f12,8Ch,0
dkey num-,4Ah,0
dkey num+,4Eh,0
dkey numet,0A6h,0
dkey num.,0A4h,0
dkey home,97h,0
dkey cuu,98h,0
dkey pgup,99h,0
dkey cul,9Bh,0
dkey cur,9Dh,0
dkey end,9Fh,0
dkey cud,0A0h,0
dkey pgdn,0A1h,0
dkey ins,0A2h,0
dkey del,0A3h,0
dw 0
proc Open ;AX: Fehlercode!
mov ax,3d00h
test bp,2000h ;/t?
jz @@2
mov al,2 ;R/W bei Translation!
@@2: DOS ;Open Read
jc @@1
mov bx,ax
mov [handle],bx
mov di,ofs ptr1
mov ax,ofs buf
cld
stosw ;Ptr1
stosw ;Ptr2
mov ax,1
stosw ;Zeilennummer
dec ax
stosw ;Fehler
@@1: ret
endp
proc Create
xor cx,cx ;Keine Attribute
or bp,1 ;Record Modus!
DOS 3ch ;Create
jc @@1
mov bx,ax
mov [handle],bx
@@1: ret
endp
proc rb ;Blocklesen
push cx dx ax
mov dx,si
mov cx,length buf ;=sizeof(buf)
mov bx,[handle]
DOS 3fh
xchg bx,ax
pop ax dx cx
ret
endp
proc Write ;Schreibt den durch DI adressierten ASCIIZ in die
;Datei und hängt 1 Leerzeichen (bei Länge≤1)
;oder 1 CRLF (Länge >1) an
push dx bx
mov dx,di
mov bx,[handle]
call ZKOUTH ;ASCIIZ ausgeben in einem Ruck
mov dx,ofs @@3 ;Space
mov ax,[di]
or al,al ;Länge Null
jz @@1
or ah,ah ;oder Eins
jz @@1
mov dx,ofs nl$ ;Newline
@@1: call ZKOUTH
pop bx dx
ret
nl$: db nl,0
@@3: db ' ',0
endp
proc Read ;liest bis zum nächsten Whitespace (Nul, Tab, Spc, EOF, EOL)
;PE: ES:DI: (leerer) Puffer
; CX: Puffer-Größe (max. Zeichenzahl-1)
;PA: Mit einem ASCIIZ gefüllter Puffer garantiert ohne
; Whitespace
; Cy=1: Fehler, BX=Fehlercode
; Nul am Anfang: Dateiende
;VR: ax bx
push si di cx
and ah,not 3 ;Null: Startphase, KEINE Zwischenphase
@@3: dec cx
@@1: mov si,[ptr1]
cmp [ptr2],si ;Füllstand erreicht?
jnz @@2
mov si,ofs buf
mov [ptr1],si
call rb ;Blocklesen ab ds:si
jc @@exi
add bx,si
mov [ptr2],bx
sub bx,si ;Null, Dateiende?
jz @@eos
@@2:
lodsb
mov [ptr1],si
call chkws
jz @@4
or ah,1 ;Startphase Ende!
jcxz @@1
stosb
jr @@3
@@4:
cmp al,0ah ;LF?
jnz @@41
inc [linenr]
@@41: test ah,1 ;Startphase?
jz @@1
@@eos:
xor al,al ;CY=0
stosb
@@exi:
pop cx di si
ret
endp
;Externe "Module" aus PROLOG.ASM
_CHKWS
_ZKONL
_INW2
_STRCOMP
_STRCPY
_AXDEZ
_UPCASE
_INLIN
_UPV
_CASE
proc StrCmp ;vergleicht ASCIIZ [DS:SI] mit Anfang von [ES:DI]
;Z=1: Übereinstimmung; dann: DI zeigt auf 1. Zeichen
;danach; sonst: VR: si
push di si
cld
@@2: cmp [by si],0
jz @@1
cmpsb
jz @@2
pop si di
ret
@@1: pop si si
ret
endp
proc WriteASCII ;Keyboardpuffer als ASCII-Datei ausgeben
;- Datei muß zum Schreiben geöffnet sein
mov [BufPtr],ofs KBDbuf
mov di,ofs mrec$
call Write
jc @@e
cld
@@1: call ReadWo
jc @@e0 ;Ende ist kein böser Fehler...
mov di,ofs obuf ;Ziel der Operation
mov si,ofs keylist
mov dx,ofs null$
call @@s
jnc @@f
mov si,ofs keylistc
mov dx,ofs ctrl$
call @@s
jnc @@f
mov si,ofs keylista
mov dx,ofs alt$
call @@s
jnc @@f
;Was bleibt ist schnöde Hexausgabe
push di
mov [by di],'$'
inc di
call Hex2Mem ;AX: Hexzahl nach DI
xor al,al
stosb ;Ende-Null
pop di
@@f: call Write
jnc @@1
@@e: ret ;Fehler-Ausstieg
@@s: ;Such mal AX im Heuhaufen!
cmp [wo si],1
jc @@se
cmp [si],ax
jz @@sf
inc si
inc si
call ScaEnd ;ohne AX einzusauen!
jr @@s ;Nächster Vergleich
@@sf: inc si
inc si
;es folgt ein StrCat, auch "Geigenkatze" genannt
push di
push si
mov si,dx
call strcpy
pop si
dec di ;Zeiger ans Ende zurück
call strcpy
pop di
@@e0: clc
@@se: ret
endp
proc Hex2Mem ;Hexzahl AX nach ES:DI schreiben, VR: DI!
xchg al,ah
call @@1
xchg al,ah
@@1: push ax cx ;Werte erhalten
mov cl,4 ;oberes Nibble auf Bit 3...0
shr al,cl ; schieben
pop cx
call @@2
pop ax
@@2: and al,0fh
add al,90h ;Hex -> ASCII
daa
adc al,40h
daa
stosb ;universell wär's mit JMP [SI]
ret
endp
proc AllList ;Alle 3 Tablisten ausgeben nach [handle]
;- Ggf. muß Datei zum Schreiben geöffnet sein
;(ansonsten geht Ausgabe auf Bildschirm)
mov si,ofs keylist
mov dx,ofs null$
call tablist
mov si,ofs keylistc
mov dx,ofs ctrl$
call tablist
mov si,ofs keylista
mov dx,ofs alt$
endp ;läuft in TabList ein!
proc Tablist ;Tabelle SI zu Kontrollzwecken ausgeben, DX zeigt auf Prolog
cld
@@2:
mov bx,[handle]
lodsw
or ax,ax
jz @@e
test bp,20h
jz @@2a
mov di,ofs obuf
call Hex2Mem
mov ax,' '
stosw ;1 Trenn-Space
push dx
mov dx,ofs obuf
call ZkoutH
pop dx
@@2a: call ZkoutH ;String DX
test bp,20h
jz @@2b
push dx
mov dx,si
call ZkoutH
mov dx,ofs nl$ ;Newline immer!
call ZKOUTH
pop dx
jr @@3
@@2b: mov di,si
call Write ;String SI
@@3: call ScaEnd
jr @@2
@@e:
ret
endp
proc ScaEnd ;rückt SI=PChar hinters Stringende
push ax
SKEND
pop ax
ret
endp
proc ReadASCII ;ASCII-Text einlesen und konvertieren
;- Datei [handle] muß zum Lesen geöffnet sein
;- Das Sclüsselwort (Header) muß bereits ausgelesen sein
;Programm kann Fehlermeldungen ausgeben!
@@2: mov di,ofs obuf
mov cx,length obuf
call Read ;1 Wort lesen
jnc @@ne
ret ;Lesefehler!
@@ne: mov dx,di
cmp [by di],0
jz @@1 ;Ende mit Allende, kein Fehler
mov si,ofs ctrl$
call StrCmp
mov dx,ofs Keylistc
jz @@4
mov si,ofs alt$
call StrCmp
mov dx,ofs Keylista
jz @@4
mov dx,ofs Keylist
@@4: cld
mov si,dx ;DI enthält Restzeichenkettenanfang
@@5: lodsw ;AX=Scancode
or ax,ax
jz @@6 ;Nichts gefunden: Syntaxfehler!
call StrComp
jz @@51
call ScaEnd ;String übergehen
jr @@5
@@51:
call WriteWo
jnc @@2
mov al,82h ;PF$
jr @@e ;Puffer voll
@@6:
cmp dx,ofs keylist ;Prologe vorhanden?
jnz m61
mov si,di ;Zur Quelle machen
mov bl,10 ;Default Dezimal
call inw2 ;Zahl einlesen
jc m61
push ax
mov al,[si]
call chkws
pop ax
jz @@51 ;Es folgt Whitespace: ok!
m61: cmp [errors],0 ;Erster Fehler?
jnz m62
call crlf
m62: WrStr obuf
WrStr sf$
mov ax,[linenr]
call axdez
call crlf
inc [errors]
jmp @@2
@@1:
cmp [errors],1 ;CY oder nicht CY!
cmc
mov al,81h ;Fehlerart SFT!
@@e: ret
endp
;*********************************************
tr31: mov al,[si]
mov di,ofs upv0
call case ;Ist Folgezeichen ' ','/','-' oder #13 ?
jnc tr2
jmp errmf ;sonst Kommandozeilenfehler
trl: ;Weißraum übergehen...
add sp,4 ;Korrektur
jr tr2
trans: ;Transientes Unterprogramm
ResizeM MemEnd ;etwas Speicher *mehr* bitte!
;für ein paar Dollar mehr
jc errm00
xor bp,bp ;BP sind meine neuen SWITCHES
WrStr intro$
mov [ParSeg],ds
mov si,81h
tr2: mov di,ofs upv0
push si
call upv ;1. Ebene
pop di
jnc tr31 ;Nächste Option muß auf Weißraum folgen
cmp si,di ;Steckengeblieben?
jz filin
jmp errmf ;FEHLER! ...sonst andere Zeichen
noopt: add sp,6 ;Stackkorrektur
filin: test bp,100h
jnz progname
or bp,100h
call term0 ;dx=si, Terminiere, si auf die Null
test bp,1 ;Record zwingend vorgegeben?
jnz oprec
call Open ;Bei Fehler Code in AX!
;Öffnet R/W bei gesetztem Trans-Bit!
jnc opsucc2
cmp al,2
jnz errm00
opRec: test bp,2000h ;Translate?
jnz errm00
call Create ;Datei zum Schreiben öffnen, setzt Bit0(BP)
tr21: jnc tr2
errm00: jmp errm
opsucc2: test bp,40h ;Show?
mov al,80h
jnz errm00 ;Already exist!
call encode
jr tr21 ;evtl. Fehler beim Einlesen
progname: test bp,2040h
JN nz,errmf ;Fehler in Kommandozeile (/t oder /s)!
mov dx,ofs rec$
test bp,1
jnz pro1
mov dx,ofs Play$
pro1: call zkout2
call crlf
test bp,200h ;/x aufgetaucht?
mov [switches],bp
jnz exeimm
sub si,4
mov [wo si+1],'C/'
mov [by si+3],' '
call calctail
call GetComspec
EX es,ds ;command.com!
xchg dx,di
ret ;zu 103h!
exeimm: call term0
call calctail
ret ;zu 103h!
Opt: test bp,100h
jnz errmf ;Keine Option HINTER Makrodatei!!
mov di,ofs upv1
call UPV ;Unterprogrammverteiler
jnc opexi
mov bl,10
call InW2 ;Dezimalzahl einlesen
jc opexi
mov [kpCmax],ax
opexi: ret
fault: ;Unerwartetes Kommandozeilenende
add sp,4 ;Stackkorrektur: Kein CALL!
test bp,40h ;Show?
jz nalli
WrStrLn out$
call AllList ;Dann ist's ja okay!
jc errm
DOS 4c00h
nalli: test bp,2000h ;Translate?
jz errmf
test bp,100h ;War Dateiname schon dran?
jz errmf
WrStrLn trans$
call tran ;Das ist auch okay
jc errm
DOS 4ch
errmf: mov al,1 ;Mein Fehlercode
errm: mov di,ofs errlist
push ax ;die komprimierte CASE-Anweisung!
call case
pushf
WrStrLn fehl$
popf
pop ax ;für Hexausgabe
mov dx,[di]
jnc TXTO1
call AHEX ;noch vorher Fehlernummer ausgeben
jr txto
txto1: cmp al,81h
jnz txto
mov ax,[errors]
call AXDEZ ;Anzahl der Fehler ausgeben
jr txto
help: mov dx,ofs hlp$
TXTO: push ax
call ZKOUT2
call crlf
pop ax ;Errorlevel rückmelden
DOS 4ch
setBin: mov al,[si] ;Folgezeichen
call UpCase
cmp al,'X'
jnz tr011
inc si ;X übergehen
or bp,8000h
tr011: or bp,4000h
ret
ResFP: xor cx,cx
mov dx,cx
mov bx,[handle]
DOS 4200h
ret
encode: ;Tastaturdatei einlesen
;jetzt auch mit ASCII-Datei
;PE: [handle]: offene Datei
; CS=DS
;PA: CY: Fehler aufgetreten!
push si dx
mov di,ofs obuf
mov cx,length obuf
call Read ;1 Wort lesen
mov si,ofs mrec$
call StrComp
jnz ecBin
call ReadASCII ;ASCII's einlesen, schiebt BufPtr hinter!
mov bx,ofs KBDbuf
xchg [BufPtr],bx
mov [BufFst],bx
jc deClos ;bei Fehler 81 in Errors die Anzahl!
jr okClos ;mit oder ohne Carry?
ecBin: call ResFP
mov dx,ofs kword
mov cx,4 ;1 Schlüssel- und 1 Code-Wort
mov bx,[handle]
DOS 3fh
jc deClos
mov ax,[kword]
cmp ax,'RM' ;MREC-Header
jz ecBinN ;Normal-binär
cmp ax,scrkw
jnz ecBinC
jr ecBinX
ecBinN: cmp [cword],'CE'
ecBinC: mov ax,11h ;Ungültige Datei
stc
jnz deClos
mov cl,-1 ;No crypted!
jr ecNoPwd
ecBinX: mov cl,0 ;Crypted!
test bp,2000h ;Translate?
jz ecNoPwd
WrStrLn lock$
call InSecP ;Paßworteingabe ohne Echo!
cmp ax,[cword]
mov ax,12h ;Falsches Paßwort
stc
jnz deClos
mov cl,0
ecNoPwd:push cx
mov dx,ofs KBDBuf
mov cx,MaxKeys*2
mov bx,[handle]
DOS 3fh ;lesen
pop cx
jc deClos
add ax,dx ;Endadresse berechnen, CY bleibt 0
mov [BufFst],ax ;Füllstand eintragen, BufPtr bleibt am Anfang
sub ax,dx
or cl,cl
jnz okClos
mov cx,ax
mov si,dx ;KBDBuf
mov ax,[cword]
call decrypt
okClos: test bp,2000h ;Translate
jnz deExi ;Nicht schließen!
deClos: pushf
push ax
mov bx,[handle]
DOS 3eh ;zumachen
pop ax
popf
deExi: pop dx si
ret
decrypt:jcxz decre ;Nichts zu descrambeln
decr1: add [si],cx
xor [si],ax
inc si
inc si
loop decr1
decre: ret
InSecP: ;Eingabe Paßwort und 'Berechnung' eines 2-Byte-Wortes
WrStr passwd$
mov di,ofs obuf
mov cx,length obuf
call InSec ;Eingabe
push di bx
mov bx,scrkw ;zufällig derselbe Startwert, warum nicht?
insecl: mov al,[es:di]
or al,al
jz insece
cbw
inc di
shl bx,1
add bx,ax
shl bx,1
xor bx,ax ;das dürfte zur Verwirrung genügen
jr insecl
insece: xchg ax,bx ;Ergebnis in AX
pop bx di
ret
BufCrypt: ;Puffer scrambeln
mov si,ofs KBDBuf
mov cx,[BufFst]
sub cx,si
jcxz bufcre ;Nichts zu scrambeln
encrypt:xor [si],ax
sub [si],cx
inc si
inc si
loop encrypt
bufcre: ret
decodex:mov ax,cs
mov ds,ax
mov es,ax
mov bp,[switches]
mov ax,ofs KBDbuf
xchg [BufPtr],ax
mov [BufFst],ax ;Pointer an Füllstand für korrekte Arbeit!
jr decode
tran: call ResFP ;Zeiger rücksetzen zum Schreiben!
mov ax,[BufFst]
mov [BufPtr],ax ;Pointer an Füllstand für korrekte Arbeit!
decode: ;Tastaturdatei schreiben
;jetzt auch als ASCII
;PE: [handle]: Na was wohl???
;CS=DS
;Beachte: Das Handle wird VOR DEM CHILDSTART erstellt!
push si dx
test bp,4000h ;Binär?
jz deASC
test bp,8000h
jz deBin
mov [kword],scrkw
WrStrLn neu$
call InSecP
mov bx,ax
WrStrLn sicher$
call InSecP
cmp bx,ax
jnz deBin0
mov [cword],ax ;das Paßwort
call BufCrypt ;mit AX als Paßwort
WrStrLn match$
jr deWri
deBin0: WrStrLn nomatch$
and bp,not 8000h ;Nicht scrambeln
deBin: mov [kword],'RM'
mov [cword],'CE'
deWri: mov bx,[handle]
mov dx,ofs kword
mov cx,4
DOS 40h
jc deClos00
mov dx,ofs KBDBuf
mov cx,[BufFst]
sub cx,dx ;Nur Länge!
DOS 40h ;schreiben
jc deClos00
cmp ax,cx
mov ax,9 ;"Out Of Disk Space"
stc
jnz deClos00
clc
jr deClos00
deASC: call WriteASCII
deClos00:
xor cx,cx
mov bx,[handle]
DOS 40h ;Truncate!
jmp deClos
coms$: db 'COMSPEC='
upv1:
dvt '?',Help
dvt 'H',Help
dvt 'X',setx
dvt 'R',setr
dvt 'V',setv
dvt 'L',setlock
dvt 'T',setT
dvt 'B',setBin
dvt 'S',Show
dvt '-',noopt
db 0 ;Abschluß
upv0:
dvt '/',Opt
dvt '-',Opt
dvt ' ',trl
dvt 13,fault
db 0
Show: mov al,[si] ;Folgezeichen
call UpCase
cmp al,'X'
jnz sh011
inc si ;X übergehen
or bp,20h
sh011: or bp,40h ;Show-Flag: Keinen EXEC-Dateinamen erwarten!
ret
setT: or bp,2000h ;Nur übersetzen!
ret
setv: or bp,800h ;Video-Check-Flag setzen
ret
setx: or bp,200h ;Direkt-Execute ohne command.com
ret
setr: or bp,1 ;Record zwingen VOR Dateiöffnung!
ret
setlock:or bp,1000h ;Tastatur-Sperr-Flag setzen
ret
setvecs: ;Vektorenverbiege-UP
push ds dx es
push cs
pop ds
DOS 3516h
SES <OldInt16>,bx
mov dx,ofs NewInt16
DOS 2516h
pop es dx ds
ret
CalcTail: ;Länge der Parameterzeile berechnen, SI zeigt drauf
mov cx,si
sub cl,80h
sub cl,[80h]
neg cl
jns ct1
mov cx,13*256 ;Endezeichen in High-Teil
mov [si],cx
ct1: mov [si],cl
mov [ParOfs],si ;eintragen
ret
GetComspec: ;DS=PSP
;PA: ES:DI: Location des Kdo-Interpreters
mov es,[2ch]
xor di,di
xor ax,ax
cld
lp3: mov cx,8 ;Länge von COMSPEC=
mov si,offset coms$
repe cmpsb ;Vergleichen
je lp2 ;gleich
dec di
lp1: scasb
jnz lp1
scasb
dec di
jnz lp3
;nicht gefunden
push ds
pop es
mov di,ofs comc$
DOS 3305h
add dl,40h
mov [di],dl ;Bootlaufwerk wird wohl kaum X sein!
lp2: ret
term0: ;Hilfsprogrämmchen, SI hinter die Null!
mov dx,si
cld
te1: lodsb
cmp al,0dh ;Zeilenende?
jz teEOL
cmp al,21h
jnc te1
mov [by si-1],0
ret
teEOL: mov [wo si-1],13*256
ret
errlist:
dvt 1,flt$
dvt 2,NoFile$
dvt 3,NoPath$
dvt 4,NoHndl$
dvt 5,AccDen$
dvt 8,NoMem$
dvt 9,DiskFl$
dvt 11h,fhead$
dvt 12h,falsch$
dvt 13h,dwp$
dvt 80h,exist$
dvt 81h,sft$
dvt 82h,pf$
dvt 0,sonst$
;Hier sind die Texte (außer Hilfetext, der ist im residenten Bereich)
fehl$ db 'FEHLER:',0
flt$ db 'Falscher oder fehlender Parameter in der Kommandozeile! (Hilfe mit /?)',0
NoFile$ db 'Datei nicht gefunden!',0
NoPath$ db 'Pfad nicht gefunden!',0
NoHndl$ db 'Keine Handles mehr!',0
AccDen$ db 'Zugriff verweigert!',0
NoMem$ db 'Zu wenig Speicher!',0
DiskFl$ db 'Diskette voll!',0
dwp$ db 'Diskette / Verzeichnis schreibgeschützt',0
exist$ db 'Datei existiert bereits!',0
rec$ db 'Aufnahme beginnt!',0
play$ db 'Wiedergabe beginnt!',0
trans$ db 'Übersetzung läuft...',0
out$ db 'Ausgabe aller Kürzel',0
intro$:
ifdef NERV
db 'MREC Tastaturmakrorekorder - UNREGISTRIERTE SHAREWARE-VERSION ZUM 30-TAGE-TEST!',nl
dz '(Copyright 1994 Berauer Computer): '
else
dz 'MREC (Copyr. 1994 Berauer Computer): '
endif
mrec$ db 'MREC#ASCII',0
sicher$ db 'Zur Sicherheit noch einmal..',0
neu$ db 'NEUES PASSWORT eingeben..',0
passwd$ db 'Paßwort: ',0
falsch$ db 'Falsches Paßwort! - Kein Zugriff!',0
nomatch$ db 'Die beiden Paßwörter stimmen nicht überein! Speichere als normale Binärdatei.',0
match$ db 'Paßwort in Datei gespeichert.',0
lock$ db '(Eingabedatei ist paßwortgeschützt)',0
fhead$ db 'Die angegebene Datei ist keine gültige Tastaturmakrodatei!',0
sonst$ db '.. Unerwarteter interner oder sonstiger Fehler!',0
sf$ db ' ... Syntaxfehler in Zeile ',0
sft$ db ' Fehler in der Makrodatei, Programm abgebrochen!',0
pf$ db 'Interner Pufferüberlauf, maximal sind '
dcd MaxKeys
db ' Tastenanschläge zulässig!',0
ifdef NERV
xnl equ (xnerv xor 13),(xnerv xor 10)
Nerv$:
db xnl
dxs xnerv,< ┌────────── Unterstützen Sie Shareware ──────────┐>
db xnl
dxs xnerv,< │ │>
db xnl
dxs xnerv,< │ Shareware ist keine Gratis-Software. │>
db xnl
dxs xnerv,< │ │>
db xnl
dxs xnerv,< │ Sie dürfen dieses Programm 30 Tage lang testen.│>
db xnl
dxs xnerv,< │ │>
db xnl
dxs xnerv,< │ Danach müssen Sie eine geringe Registrierungs- │>
db xnl
dxs xnerv,< │ gebühr entrichten. │>
db xnl
dxs xnerv,< │ │>
db xnl
dxs xnerv,< │ Für den geringen Registrierungsbetrag lohnt │>
db xnl
dxs xnerv,< │ sich eine Raubkopie wirklich nicht!! │>
db xnl
dxs xnerv,< │ │>
db xnl
dxs xnerv,< └───────────────────────────── Taste drücken... ─┘>
db xnl
db xnerv ;Abschlußzeichen
endif
;und hier die transienten Arbeitszellen
PGMEnd: ;Ende initialisierte Variablen
ptr1 dw ?
ptr2 dw ?
linenr dw ?
errors dw ?
kword dw ? ;Kennwort
cword dw ? ;Codewort
buf db 80h dup (?) ;1 CP/M-Sektor Lesepuffer
obuf db 16 dup (?)
MemEnd:
ENDC
Vorgefundene Kodierung: OEM (CP437) | 1
|
|