Dem Klicken ein Ende: Hoch- und Tiefsetzen auf Tastendruck

WORDPLUS ist eine leistungsfähige Textverarbeitung, allerdings mit einigen zum Teil erheblichen Mängeln. Eines dieser Probleme wird mit dem folgenden Programm beseitigt: Das Hoch- und Tiefstellen kann ab sofort über einen einzigen Tastendruck erreicht werden.

Es waren allerdings gewaltige maschinensprachliche Verrenkungen notwendig, bis das angestrebte Ziel erreicht werden konnte. Dabei ist das Prinzip relativ einfach: Ein kleines speicherresidentes Assemblerprogramm fängt alle GEM-Calls der Textverarbeitung ab und prüft, ob innerhalb einer EVNT_MULTI-Warteschleife die Tastatur abgefragt werden soll. Wenn ja, so wird anschließend überprüft, ob eine der Tasten HELP und UNDO betätigt wurde. Ist dies der Fall, so schreibt das Programm eine 'gefälschte' Meldung in den Ereignispuffer, der WordPlus glauben macht, der Anwender hätte einen Menüeintrag angeklickt. Das ist im Prinzip alles.

Kommen wir zu einer genaueren Beschreibung des Assembler-Programms: Die Speicherbedarfsberechnung am Beginn dürfte mittlerweile allseits bekannt sein. Interessant wird es in den Zeilen 22 bis 33: Hier schmuggelt sich das Programm in den ansonsten nicht benutzten TRAP #3-Vektor ein und liest den TRAP #2-Vektor aus, der normalerweise für alle GEM-Calls zuständig ist - schließlich muß das Programm ja wissen, wo der 'übliche' GEM-Einsprung liegt.

Der Kern des Programms beginnt natürlich beim Label gemvektor, daß bei jedem TRAP #3 automatisch angesprungen wird. Hier muß zunächst überprüft werden, ob ein AES- oder VDI-Aufruf stattfand, was man aus dem Register d0 entnehmen kann. Im Falle eines AES-Calls steht dann in a0 ein Zeiger auf dem sogenannten AES-Parameterblock, der eine Tabelle auf die vom AES benutzten Arrays enthält. Mit deren Hilfe kann man nun die Art des Aufrufs feststellen.

Wenn nun AES aufgerufen werden soll, so legt man einfach die Rücksprungadresse und den Prozessor-Status(!) auf den Stapel, und springt zu der vorher erfragten Einsprungadresse. AES beendet mit einem rte (Return from exeption). Der Rest des Programms dürfte durch die Kommentare im Listing relativ leicht zu durchschauen sein. Wichtig ist natürlich, daß auch unser Programm mit einem rte endet, da es ja durch einen TRAP #3 aufgerufen wird.

Nun wird sich manch einer fragen: Woher weiß denn WordPlus überhaupt, daß es das AES über TRAP #3 und nicht - wie gewöhnlich - über einen TRAP #2 ruft? Ganz einfach: dazu wird WordPlus ganz gepatched. Benutzen Sie dazu bitte das kurze GFA-BASIC-Programm, daß diesen Patch an der Version 1.89 (und nur an dieser!) automatisch vornimmt. Sollte es in Zukunft eine neue Version von WordPlus geben, so werde ich selbstverständlich auch dazu ein Patch-Programm erstellen, aber vielleicht kommen die Autoren dieses Programms bis dahin vielleicht selbst auf die Idee, daß unter den ST-Anwendern nicht nur absolute Maus-Fanatiker sind.

Noch eine Frage: Warum leiten wir nicht den TRAP =#=2 selber auf unsere Routine, was doch den Patch ersparen würde? Ganz einfach: Weil es nämlich nicht geht. Das heißt, es geht schon, nur stürzt Ihr Rechner dann ab, sobald sich außer WordPlus auch noch Accessories im Speicher befinden. Bitte fragen Sie mich jetzt nicht, warum dem so ist - ich weiß es nämlich selber nicht, und sollte ein Leser wissen, warum das so ist, so bitte ich diesen, mir das Geheimnis zu verraten, das mich schlaflose Nächte gekostet hat. So ist das Problem jedenfalls nicht sehr elegant gelöst, aber es funktioniert.

Es bleibt noch zu erwähnen, daß 1STPATCH.PRG unbedingt vor dem ersten Laden des gepatchten WordPlus gestartet werden muß, da ja sonst der TRAP #3 die schönsten Bomben, aber leider keine GEM-Calls zur Folge hat. Übrigens „Hochstellen“ können Sie über HELP, „Tiefstellen“ mit UNDO ein- und auschalten.

Das war's - ich wünsche Ihnen viel Spaß beim Abtippen; den Mathe-Hausaufgaben auf dem ST steht nun nichts mehr im Wege!

GST 68000 Macro Assembler	C:\1STPATCH.ASM

		***************************************************
		*                                                 *
		*    1st WORD PLUS        Hoch-/Tiefsetzen auf    *
		*    von Martin Pauly	         HELP und UNDO    *
		*                                                 *
		***************************************************

00000008	title	equ	8	; Menütitel	für Sub- und Superscript
00000054	index1	equ	84	; Index für	Superscript
00000055	index2	equ	85	; Index für	Subscript

01	00000000				section code	; DRI: .text
							opt abs			; DRI: entfällt
'
01	00000000 206F0004		move.1 4(sp),a0	; Die üblichen Berechnungen...
01	00000004 2C3C00000100	move.l #$100,d6
01	0000000a DCA8000C		add.l 12(a0),d6
01	0000000E DCA80014		add.l 20(a0),d6
01	00000012 D08001C		add.l 28(a0),d6

01	00000016 2F3C0000004A	move.l #gemvektor,-(sp)
01	0000001C 3F3C0023		move.w #35,-(sp)
01	00000020 3F3C0005		move.w #5,-(sp)
01	00000024 4E4D			trap #13 ; Einsprung über TRAP #3	initialisieren
01 00000026 508F			addq.l #8,sp

01	00000028 2F3CFFFFFFFF	move.l #-1,-(sp)
01	0000002E 3F3C0022		move.w #34,-(sp)
01	00000032 3F3C0005		move.w #5,-(sp)
01	00000036 4E4D			trap #13	; 'A1ten' GEM-Vektor (TRAP #2)	merken
01	00000038 508F			addq.l #8,sp
01	0000003A 23C000000000	move.l d0,oldvektor

01	00000040 4267			clr.w -(sp)
01	00000042 2F06			move.l d6,-(sp)
01	00000044 3F3C0031		move.w #$31,-(sp)
01	00000048 4E41			trap #1	; ...aber resident halten (KEEP	PROCESS)


01	0000004A				gemvektor:
01	0000004A 0C4000C8		cmpi.w #$c8,d0	; AES-Aufruf oder 'nur' VDI?
01	0000004E 6618			bne.s normal	; Nicht um's VDI kümmern!

01	00000050 2041			move.l d1,a0	; Zeiger auf AES-Parameterblock
01	00000052 23C800000004	move.l a0,adsave	; retten
01	00000058 2250			move.l (a0),a1	; a1 enthält jetzt Pointer	auf	Contrl-Array

01	0000005A 0C510019		cmpi.w #25, (a1)	; EVNT_MULTI Aufruf der Applikation? (Opcode)
01	0000005E 6608			bne.s normal	; Nein, dann normal weiter!

GST 68000 Macro Assembler	C:\1STPATCH.ASM

01	00000060 487900000070	pea return		; Rücksprungadresse und
01	00000066 40E7			move.w sr,-(sp)	; Statusregister auf den Stack werfen

01	00000068				normal:
01	00000068 207900000000	move.l oldvektor,a0
01	0000006E 4ED0			jmp (a0)		; normalen TRAP	#2 ausführen

01	00000070	return:
01	00000070 207900000004	move.l adsave,a0
01	00000076 2268000C		move.l 12(a0),a1	; GEM Intout-Array
01	0000007A 24680010		move.l 16(a0),a2	; GEM Addrin-Array
01	0000007E 3011			move.w (a1),d0		; Ereignis-Bitfeld von EVNT_MULTI
01	00000080 02400001		andi.w #1,d0		; Taste	gedrückt?
01	00000084 673A			beq.s ende			; Nein?	Macht nichts.
01	00000086 0C696200000A 	cmpi.w #$6200,10(a1) ; Scancode der HELP-Taste im Hi-Byte
01	0000008C 6616			bne.s test2
01	0000008E 2452			move.l (a2),a2		; Superscript
01	00000090 32BC0010		move.w #16,(a1)	; EVNT_MESAG 'einschmuggeln'
01	00000094 34FC000A		move.w #10,(a2)+	; Menu_Selected
01	00000098 429A			clr.l (a2)+			; Filler
01	0000009A 34FC0008		move.w #title,(a2)+	; Menü_Titel
01	0000009E 34BC0054		move.w #index1,(a2)	; Menü_Index
01	000000A2 601C			bra.s ende
01	000000A4			test2:
01	000000A4 0C696100000A	cmpi.w #$6100,10(a1)	; Oder vielleicht UNDO gedrückt?
01	000000AA 6614			bne.s ende
01	000000AC 2452			move.l (a2),a2
01	000000AE 32BC0010		move.w #16,(a1)	; s.o.
01	000000B2 34FC000A		move.w #10,(a2)+
01	000000B6 429A			clr.l (a2)+
01	000000B8 34FC0008		move.w #title,(a2)+
01	000000BC 34BC0055		move.w #index2,(a2)

01	000000C0	ende:
01	000000C0 4E73	rte

02	00000000				section storage ; DRI: .bss
02	00000000			oldvektor:
02	00000000 00000004		ds.l	1
02	00000004	adsave:
02	00000004 00000004		ds.l	1

							end

Listing 1: Assembler Listing zum Hoch- und Tiefsetzen.

' Patch für WORDPLUS.PRG zu 1STPATCH 
' von Martin Pauly
' ST-Computer 11/87
'
' Erst Backup dann Patch
'
Open "U",#1,"WORDPLUS.PRG"
Seek #1,141355 
Out #1,67 
Close #1

Listing 2: Dieser kleine Eingriff auf der Diskette muß sein (Bitte erst eine Kopie machen)


Martin Pauly
Aus: ST-Computer 11 / 1987, Seite 96

Links

Copyright-Bestimmungen: siehe Über diese Seite