Das Desktop bietet bisher die Möglichkeit, mehrere Dateien oder Icons zu selektieren. dabei muss man bei gedrĂŒckter Shift-Taste die Dateien mit dem Mauszeiger anklicken. Ab TOS 1.4 kann man Dateien auch verschieben, das heiĂt, die Quelldatei wird kopiert und anschliessend gelöscht. Sollen Dateien verschoben werden, muss die Control-Taste gedrĂŒckt sein. Wollte man bisher mehrere Dateien verschieben, musste man die Control- und Shift-Taste drĂŒcken und die Dateien mit dem Mauszeiger selektieren. Das Programm Control-Shift-Maus ( CS-Maus) ermöglicht jetzt mit Hilfe der rechten Maustaste ein Verschieben oder Kopieren von einzelnen oder mehreren Dateien ohne zusĂ€tzliches DrĂŒcken der Shift-oder Control-Taste.
Sollen mit CS-Maus mehrere Dateien ausgewĂ€hlt werden, muĂ man anstelle der Shift-Taste die rechte Maustaste drĂŒcken. Beim Verschieben von Dateien wird auch die Control-Taste durch die rechte Maustaste ersetzt. Das Selektieren der Datei geschieht wie bisher mit einem Klick der linken Maustaste. Will man mit CS-Maus mehrere Dateien verschieben, drĂŒckt man einfach die rechte Maustaste wĂ€hlt die Dateien aus und verschiebt sie bei gedrĂŒckter rechter Maustaste in das Zielverzeichnis. Das Selektieren oder Verschieben mehrerer Dateien ist wie bisher mit der Shift-oder Control-Taste möglich. Auch das Kopieren von einem nicht aktiven Fenster in das aktive bei gedrĂŒckter rechter Maustaste ist wie bisher möglich.
CS-Maus kann man aus dem Auto-Ordner starten oder direkt vom Desktop. Will man CS-Maus ausschalten, muĂ das Programm ein zweites Mal gestartet werden. Es wird dann die Meldung âCS-Maus AUSâ ausgegeben. Das Einschalten geschieht durch ein erneutes Starten des Programms. CS-Maus ist nur im Desktop aktiv; sobald ein Programm gestartet wird, schaltet es sich selber aus.
Installation
Nun zur Beschreibung des Listings. Das Programm springt zuerst zur Installierungsroutine (INSTALL). Dort werden eine neue Mausroutine installiert und die Adressen von kbshift und run geholt. Die Routine Kbdvbase (XBIOS 34) liefert einen Zeiger auf die KBDVECS-Struktur. In dieser Struktur ist der Mausvektor (.mousevec) enthalten. Das Betriebssystem springt bei jeder Mausbewegung durch diesen Vektor. Da CS-Maus die neue Mausroutine mit dem XBRA-Protokoll anmeldet, kann es auch feststellen, ob CS-Maus schon installiert ist. Eine Verfolgung der Kette ist nur dann möglich, wenn sich jede neue Mausroutine an das XBRA-Protokoll hÀlt. War CS-Maus schon installiert, wird das Programm ein- oder ausgeschaltet. Dazu wird das Flag MAUS-OFF invertiert. Dieses befindet sich 13 Bytes hinter der schon installierten Mausroutine. War die Installation erfolgreich, werden die neue Mausroutine (NEW_MOUSE) und die VBL-Routine (NEU_VBL) resident im Speicher gehalten.
Neue Mausroutine
Wird CS-Maus zum ersten Mal installiert, muĂ zwischen einem Start aus dem Auto-Ordner und einem vom Desktop unterschieden werden. Deshalb wird versucht, eine Applikation anzumelden (APPL_INIT AES 10). Wird CS-Maus aus dem Auto-Ordner gestartet, ist die ap_version gleich Null, da das AES noch nicht initialisiert ist. Bei einem Start vom Desktop wird der alte Mausvektor in OLD -VEC gespeichert und die Adresse der neuen Mausroutine in die KBDVECS-Struktur eingetragen. Da der Mausvektor erst nach dem Starten aller Programme aus dem Auto-Ordner belegt wird, muĂ man bei einem Start von CS-Maus aus dem Auto-Ordner anders Vorgehen. Dabei wird eine VBL-Routine {NEU_VBL) installiert. Diese wartet jetzt solange, bis der Mausvektor ĂŒberschrieben wird. Ist dies der Fall, wird wie beim Starten vom Desktop der alte Mausvektor in OLD_VEC gespeichert und die Adresse der neuen Mausroutine in die KB-DVECS-Struktur eingetragen. Danach wird die VBL-Routine gelöscht.
Aufbau eines Mauspaketes
- Byte Header von $F8 bis $FB *
- Byte Mausbewegung in x-Richtung
- Byte Mausbewegung in y-Richtung
_run und kbshift
Die Zeiger j-un und kbshift sind in der SYSHDR-Struktur abgelegt. Das ist aber erst ab TOS 1.2 der Fall. Bei Àlteren TOS-Versionen liegen jun bei $602C und kbshift bei $E1B. Den Zeiger auf die SYSHDR-Struktur erhÀlt man durch die Systemvariable _sysbase ($4-f2). _run enthÀlt die Adresse des Zeigers der aktuellen Basepage. Die LÀnge des Programmcodes ist mit einem Offset von $C in der Basepage abgelegt. Ist die LÀnge des Programmcodes gleich Null, ist das aktuelle Programm das Desktop. _run wird dazu benutzt, CS-Maus auszuschalten, wenn ein Programm gestartet wird. Der Zeiger kbshift zeigt auf ein Byte, in dem der Tastaturstatus abgelegt ist. Dabei entspricht Bit 0 der rechten Shift-Taste und Bit 2 der Control-Taste. Man kann den Tastaturstatus auslesen oder setzen.
Mauspakete
Der Tastaturprozessor schickt bei jeder Mausbewegung Pakete zur Mausroutine. Diese Mauspakete bestehen aus drei Bytes, deren Adresse ist im Register A0 enthalten. Das erste Byte enthĂ€lt den Header. In diesem Byte ist der Status der Mausknöpfe abgelegt. Dabei entspricht B it 0 der rechten und Bit 1 der linken Maustaste. Ist eine Taste gedrĂŒckt, ist das entsprechende Bit gesetzt. Der Wert des Headers liegt bei Mausbewegungen von $F8 bis $FB. Die relative Mausbewegung in x-Richtung enthĂ€lt das zweite Byte. Die Mausbewegung in y-Richtung ist im dritten Byte enthalten. Die neue Mausroutine, die nach der erfolgreichen Installation jetzt jedes Mauspaket zuerst erhĂ€lt, benötigt nur das erste Byte.
Shift und Control
Die neue Mausroutine testet zuerst, ob ein Mauspaket angekommen ist; danach, ob CS-Maus ein- oder ausgeschaltet ist. Wenn der Programmcode gleich Null ist (Desktop aktiv), wird der Maus-Header auf einen rechten Mausdruck getestet. Ist dies der Fall, wird der Zeiger auf den Tastaturstatus geholt. Nun setzt man Bit 0 (Shift) und Bit 2 (Control). Die beiden Bits werden gelöscht, sobald eine Mausbewegung erfolgt, bei der nicht die rechte Maustaste gedrĂŒckt ist. Auch wenn das aktuelle Programm nicht mehr das Desktop ist, werden die Bits gelöscht.
Literatur:
[1] Atari ST Profibuch, Sybex
[2] ST Computer 6/90, Seite 83, Springmaus
**Bit-Belegung des Tastaturstatusâ**
Bit 0: Shift-Taste rechts *
Bit 1: Shift-Taste links Bit 2: Control-Taste *
Bit 3: Alternate-Taste
Bit 4: Caps Lock gesetzt
Bit 5: Maustaste rechts (Clr Home)
Bit 6: Maustaste links (Insert)
Bit 7: reserviert
Offset | Bezeichnung | Beschreibung
------ | ----------- | ------------
0 | midivec | Midi-Eingabe
4 | vkbderr | Tastaturfehler
8 | vmiderr | Midi-Fehler
12 | statvec | Status von IKBD lesen
16 | mousevec | Mausabfrage *
20 | clockvec | Uhrzeitabfrage
24 | joyvec | Joystick-Abfrage
28 | midisys | Midi-Systemvektor
32 | ikbdsys | | KBD-Systemvektor
**Belegung der KBDVECS-Struktur**
Offset |
Bezeichnung |
Beschreibung |
0 |
os_entry |
Einsprungadresse |
2 |
os_version |
TOS-Version * |
4 |
os_start |
Startadresse des OS-Codes |
8 |
os_base |
Anfangsadresse des Betriebssystems |
12 |
os_membot |
Beginn des freien RAM |
16 |
os_shell |
Default Shell |
20 |
os_magic |
Zeiger auf GEM-Magic-Variable |
24 |
os_gendat |
Erstellungsdatum BCD-Format |
28 |
os_palmode |
PAL oder NTSC |
30 |
os_gendatg |
Erstellungsdatum GEMDOS-Format |
Folgende Variablen erst ab TOS 1.2
 |
 |
 |
32 |
*_root |
Zeiger auf âmifl'-Liste |
36 |
kbshift |
Zeiger auf Bit-Belegung des Tastaturstatus * |
40 |
**_run |
Zeiger auf aktuelle Basepage * |
Belegung der SYSHDR-Struktur
*-------------------------*
* Control-Shift-Maus *
* by Ralf Stachs *
* ------------------------*
* (c) 1991 MAXON Computer *
* ------------------------*
;TRAPS
GEMDOS equ 1
BIOS equ 13
XBIOS equ 14
*******************************************
;Programmteil der resident im Speicher
;gehalten wird v. RESI_ANFANG bis RESI_ENDE
*******************************************
TEXT
RESI_ANFANG:
bra INSTALL
;zur Installationroutine springen
;Flags
******
;FIRST ->Rechte Maustaste zum ersten mal gedruckt
; 0->Rechte Maustaste noch nicht gedrĂŒckt
; 1->Rechte Maustaste war schon gedrĂŒckt
;MAUS_OFF ->schaltet CS_Maus an oder aus
; $00 CS_Maus an
; $FF CS_MAUS aus
FIRST: dc.b 0
MAOS_OFF: dc.b 0
dc.b "XBRAâ ;XBRA Protokoll
dc.b "RS11" ;eigene Kennung
0LD_VEC: dc.l 0 ;alter Mausvektor
;neue Mausroutine
*****************
NEW_MOUSE:
movem.l d0/a0-a2,-(sp) ;Register retten
;Maus Header?
move.b (a0),d0 ;Header Kopf in d0
cmp.b #$f8,d0 ;kleiner $f8
blt ENDE ;ja
cmp.b #$fb,d0 ;gröĂer $fb
bgt ENDE ;ja
;Maus ausgeschaltet TOS?
move.l A_MOUSE_FLAG,a1 ;Flag fĂŒr Maus aus (MOUSE_FLAG)
tst.b (a1) ;Maus ausgeschaltet
bne ENDE ;ja
;CS_Maus ausgeschaltet7
tst.b MAUS_OFF ;CS_MAUS ausgeschaltet
bne ENDE ;ja
;aktuelles PRG Desktop?
move.l A_RUN,a1 ;a1=Adresse auf Zeiger der aktuellen Basepage
move.l (a1),a2 ;a2=Zeiger auf Basepage
tst.l $C(a2) ;LĂ€nge des Programmcode = 0
bne SP_11 ;nein, nicht Desktop
;Rechte Maustaste gedrĂŒckt
btst.b #0,(a0) ;rechte Maustaste gedrĂŒckt
beq SP_11 ;nein, Flags und Tasten löschen
;wenn FIRST noch gesetzt
;Rechte Maustaste zum ersten mal gedrĂŒckt
tst.b FIRST ;zum ersten mal
bne ENDE ;nein
;Control und Shift Taste setzen
move.l A_KBSHIFT,a1 ;Adresse von Kbshift in a1
or.b #%00000101,(a1) ;Control Taste (Bit 2) setzen
;und Shift Taste (Bit 0) setzen
move.b #1,FIRST ;Flag setzen
bra ENDE
;Control und Shift Taste löschen
SP_11: tst.b FIRST ;First Flag noch gesetzt
beq ENDE ;Nein, dann Ende
move.l A_KBSHIFT,a1 ;Adresse von Kbshift in a1
and.b #%11111010,(a1) ;Control-Taste (Bit 2) löschen
;und Shift Taste (Bit 0) löschen
move.b #0,FIRST ;Flag löschen
;alte Mausroutine anspringen
ENDE: movem.l (sp)+,d0/a0-a2 ;Register zurĂŒckschreiben
move.l OLD_VEC,-(sp) ;alte Mausroutine
rts ;anspringen
;VBL-Routine bei Start aus AUTO-Ordner
**************************************
dc.b "XBRA" ;XBRA Protokoll
dc.b "RS12" ;eigene Kennung
dc.l 0 ;alter Vektor nicht benutzt
NEU_VBL:
move.l A_KBDV,a0 ;kdbv Adresse nach a0
lea 16(a0),a1 ;Adresse Mausvektor a1
lea OLD_VEC,a0 ;alter Mausvektor vom Betriebssystem
cmp.l (a0)+,(a1)+ ;alter Mausvektor noch da
beq SP_3 ;ja
move.l -(a1),OLD_VEC ;alten Mausvektor sichern
move.l #NEW_MOUSE,(a1) ;neue Mausroutine initialisieren
move.l A_VBL_SLOT,a0 ;vbl-Slot löschen
move.l #0,(a0)
SP_3: rts
;Adressen
*********
;A_KBDV -> Adresse der kbdv Tabelle
;A_VBL_SLOT -> Adresse des VBL-Slot
;A_MOUSE_FLAG -> Adresse von MOUSE_FLAG
; MOUSE_FLAG = 0 ->Maus-Interuptbehandlung ein
; MOUSE_FLAG <>0 ->Maus-Interuptbehandlung aus
;A_KBSHIFT -> Adresse von Kbshift
;A_RUN -> Adresse von Zeiger auf aktueller Basepage
A_KBDV: dc.l 0
A_VBL_SLOT: dc.l 0
A_MOUSE_FLAG: dc.l 0
A_KBSHIFT: dc.l 0
A_RUN : dc.l 0
RESI_ENDE:
*************************
;Instalierung von CS_Maus
*************************
;gesammten Programmspeicher belegen
EVEN
INSTALL:
move.l sp,a6 ;Adresse BASEPAGE
lea USTACK,sp ;neuer Stack
move.l 4(a6),a6 ;Speicher belegen
move.l $c(a6),a4
adda.l $14(a6),a4
adda.l $1c(a6),a4
pea 256(a4)
pea (a6)
clr.w -(sp)
move.w #74,-(sp) ;Mshrink aufrufen
trap #GEMD0S
lea 12(sp),sp
;Adresse KBDVECS holen
move #34,-(a7) ;Kbdvbase aufrufen
trap #XBIOS
addq.l #2,a7
move.l d0,A_KBDV ;Adresse der Vektortabelle sichern
;CS_Maus schon installiert?
move.l A_KBDV,a1 ;Adresse der Vektortabelle nach a1
move.l 16(a1),a2 ;Adresse von Mausroutine in a2
move.l a2,a0 ;a0 zum suchen
SP_1: cmp.l #"RS11",-8(a0) ;CS_Maus schon vorhanden
beq SP_2 ;ja, CS_MAUS init.
cmp.l #"XBRA",-12(a0) ;XBRA Kennung
bne SP_4 ;CS_Maus installieren
;Original Mausvektor oder kein XBRA Protokoll
move.l -4(a0),a1 ;Adresse der nÀchsten Mausroutine
move.l a1,a0 ;von a1 nach a0
bra SP_1 ;weiter
;CS_Maus war schon installiert
*****************************
SP_2: not.b -13(a0) ;MAUS_OFF invertieren
bne SP_7
;Meldung CS_Maus einschalten
pea STRING_3
move.w #9,-(sp)
trap #GEMDOS
addq.l #6,sp
bra SP_8 ;ende
;Meldung CS_Maus auschalten
SP_7: pea STRING_4
move.w #9,-(sp)
trap #GEMDOS
addq.l #6,sp
;PRG beenden
SP_8: clr.w -(sp) trap #GEMDOS
;CS_MAUS instalieren
********************
;alten Vektor sichern
SP_4: lea OLD_VEC,a0
move.l a2,(a0)
;AES-anmelden
move.w #10,d0 ;Applikation anmelden
bsr AES_INIT ;AES aufrufen
tst.w AES_GLOBAL ;starten aus AUTO-Ordner
beq SP_6 ;ja, keine ap_version
;Vom Desktop starten
********************
;maus installieren
lea DESKTOP,a0 ;Adresse von Desktop nach a0
pea (a0)
move.w #38,-(sp) ;Supexec aufrufen
trap #XBIOS
addq.l #6,sp
bra SP_5
;Aus AUTO-Ordner starten
************************
;Unterprogramm im Supervisor-Modus ausfĂŒhren
SP_6: lea AUTO,a0 ;Adresse von auto nach a0
pea (a0)
move.w #$26,-(sp) ;Supexec aufrufen
trap #XBIOS
addq.l #6,sp
;Adresse von MOUSE_FLAG holen
SP_5: dc.w $a000 ;Adresse negative Line-A Variabelen
sub.l #$153,a0 ;Adresse MOUSE-FLAG berechnen
move.l a0,A_MOUSE_FLAG ;MOUSE FLAG merken
;installierung i.o.
pea STRING_1
move.w #9,-(sp)
trap #GEMDOS
addq.l #6,sp
;Speicherplatz fĂŒr Mausroutine
;resident im Speicher halten
clr.w -(sp)
pea RESI_ENDE-RESI_ANFANG+256
move.w #49,-(a7) ;Ptermres aufrufen
trap #GEMDOS
***************************
;Unterprogramme von CS_MAUS
***************************
;PRG im Supervisor-Modus Mausroutine installieren
*******************************************
;starten aus AUTO Ordner
;VBL installieren
AUTO: move.w $454,d0 ;Anzahl der VBL-Routinen (nvbls)
lsl #2,d0 ;Anzahl*4
move.l $456,a0 ;Zeiger auf VBL (_vblqueue)
clr d1 ;ZĂ€hler
WEITER: tst.l 4(a0,d1) ;VBL Slot frei
beq FREI ;ja
add #4,d1 ;nÀchster Slotpointer
cmp.w d0,d1 ;alle slots abgefragt
bne WEITER
;CS_Maus nicht initialisieren
pea STRING_2 ;Alle Slots besetzt
move.w #9,-(sp)
trap #GEMDOS
addq.l #6,sp
clr.w -(sp) ;PRG beenden
trap #GEMDOS
FREI: lea 4(a0,d1),a2 ;Adresse Slot in a2
lea NEU_VBL,a1 ;Adresse neue Routine
move.l a1,(a2) ;neue Routine einhÀngen
lea A_VBL_SLOT,a1 ;Slot Adresse
move.l a2,(a1) ;sichern
;Adresse von Kbshift ermitteln und
;Adresse von Zeiger auf aktueller Basepage
SP_10: move.l #$e1b,A_KBSHIFT ;Vorgabe fĂŒr TOS 1.0 (Kbshift)
move.l #$602c,A_RUN ;Vorgabe fĂŒr TOS 1.0 (Basepage)
move.l $4f2,a0 ;(a0) _sysbase
cmp.w #$0100,2(a0) ;TOS 1 0
beq SP_9 ;ja
move.l 36(a0),a1 ;(a1) Adresse von Kbshift
move.l a1,A_KBSHIFT ;Adresse merken
move.l 40(a0),a1 ;(a1) Adresse auf Zeiger der aktuellen Basepage
move.l a1,A_RUN ;Adresse merken
SP_9: rts
;PRG im Supervisor-Modus Mausroutine instal1ieren
*******************************************
;Starten vom Desktop
DESKTOP:
move.l A_KBDV,a0 ;Keyboardadresse nach a0
lea NEW_MOUSE,a1 ;Adresse neue Mausroutine
move.l a1,16(a0) ;neuen Vektor setzen
;Kbshift und Zeiger auf
bra SP_10 ;aktueller Basepage ermitteln
;AES aufrufen
*************
AES_INIT:
lea CONTRL,a0 ;Adresse CONTRL nach a0
move.w d0,(a0)+ ;Opcode
clr.w (a0)+ ;eintrÀge INIT_IN
move.w #1,(a0) ;eintrÀge INIT_OUT
clr.w (a0)+ ;eintrÀge ADDR_IN
clr.w (a0) ;eintrÀge ADDR_OUT
move.l #AES_DATA,d1 ;Adresse AES-Array
move.w #$c8,d0 ;AES-Aufruf
trap #2
rts
DATA
EVEN
STRING_1:
dc.b 27,"E",27,"p"
dc.b 13,10,"+***************************+"
dc.b 13,10,"+ +"
dc.b 13,10,"+ Control-Shift-Maus 1.0 +"
dc.b 13,10,"+ CS_MAUS +"
dc.b 13,10,"+ +"
dc.b 13,10,"+ 7/91 Ralf Stachs +"
dc.b 13,10,â+ ST Computer +"
dc.b 13,10,"+ +"
dc.b 13,10,"+***************************+"
dc.b 13,10
dc.b 27,"q",0
EVEN
STRING_2:
dc.b 13,10,"Alle VBL-Slots besetzt",13, 10,0
EVEN
STRING_3:
dc.b 27,"E"
dc.b 13,10,"*****************"
dc.b 13,10,"* CS_MAUS EIN *"
dc.b 13,10,"*****************",0
EVEN
STRING_4:
dc.b 27,"E",27,"p"
dc.b 13,10,"*****************"
dc.b 13,10,"* CS_MAUS AUS *"
dc.b 13,10,"*****************"
dc.b 27,"q",0
EVEN
AES_DATA:
dc.l CONTRL
dc.l AES_GLOBAL
dc.l INIT_IN
dc.l INIT_OUT
dc.l ADDR_IN
dc.l ADDR_OUT
BSS
AES_GLOBAL: ds.w 15
CONTRL: ds.w 10
INIT_IN: ds.w 128
INIT_OUT: ds.w 128
ADDR_IN: ds.l 128
ADDR_OUT: ds.l 128
ds.b 100
USTACK: ds.w 0