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)