home *** CD-ROM | disk | FTP | other *** search
- *** FME.asm - FastMemEmulator V1.0 - © 30.09.1989 by Holger Lubitz
- ***
- *** Patcht die AllocMem()-Routine so, daß keine explizite Anforderung von
- *** FastMem mehr möglich ist, wenn nicht gleichzeitig das MEMF_LARGEST-Bit
- *** gesetzt ist. Bei bereits installiertem Patch wird dieser entfernt.
- ***
- *** Sinn der Sache ist, an sich interessante Programme wie Evolution (Fish
- *** 239) oder Crud, Demon und Life (alle Fish 249), die sich aber aus
- *** unerfindlichen Gründen nicht ohne FastMem zufriedengeben, auch auf
- *** Amigas ohne FastMem (512k oder 1MB mit Fatter Agnus) zum Laufen zu
- *** bringen, ohne in den Programmen selbst herumpatchen zu müssen.
- ***
- *** Von der Benutzung dieses Programms auf Amigas MIT FastMemory wird
- *** vorsorglich abgeraten ! (Auch wenn es normalerweise nichts schaden
- *** dürfte, aber sicher ist sicher)
- ***
- *** Quellen: A68k von Fish 186, BLink von Fish 110, small.lib von Fish 92
- ***
- *** 1> A68k FME.asm
- *** 1> BLink FME.o small.lib to FME
- ***
- *** FME ist zuerst im AmigaJUICE 17 (November 1989) erschienen.
- *** Die jeweils neueste AmigaJUICE-Ausgabe gibts gegen Einsendung einer
- *** Leerdiskette mit frankiertem Rückumschlag (1,70 DM Porto) bei:
- *** AmigaJUICE, c/o Holger Lubitz, Postfach 1431, 3070 Nienburg/Weser
- ***
- *** FME darf frei kopiert werden, wenn das Programm zusammen mit dem Source
- *** und unverändert weiterkopiert wird. (diese Vermerke müssen drinbleiben !)
- ***
- *** P.S.: 380 Bytes für dieses Programm sind ziemlich kurz, oder ?
- *** An alle: Lernt Assembler, wenn ihr den Amiga WIRKLICH effizient
- *** programmieren wollt !!
-
- XREF _LVOAllocMem
- XREF _LVOClose
- XREF _LVOCloseLibrary
- XREF _LVODelay
- XREF _LVOForbid
- XREF _LVOFindTask
- XREF _LVOFreeMem
- XREF _LVOGetMsg
- XREF _LVOOldOpenLibrary
- XREF _LVOOpen
- XREF _LVOOutput
- XREF _LVOPermit
- XREF _LVOReplyMsg
- XREF _LVOSetFunction
- XREF _LVOWaitPort
- XREF _LVOWrite
-
- _AbsExecBase = 4
- ThisTask = 276
- pr_CLI = $ac
- pr_MsgPort = $5c
- MODE_OLDFILE = 1005
-
- SECTION "",CODE
-
- *** Registerbelegung: A6 reserviert für Exec-Base
- *** A5 reserviert für Adresse der Taskstruktur
- *** A4 reserviert für DOS-Base
- *** A3 reserviert für Adresse des Speicherblocks
- *** D7 reserviert für Länge des Speicherblocks
- *** D6 reserviert für Fenster-Handle
-
- *** Eigenen Task finden
-
- move.l _AbsExecBase,a6 ; Exec-Basisadresse
- move.l ThisTask(a6),a5 ; FindTask(0) - Thanxx Fridtjof
-
- *** DOS-Library öffnen
-
- lea dosname(pc),a1 ; Zeiger auf 'dos.library'
- jsr _LVOOldOpenLibrary(a6) ; Version ist egal
- move.l d0,a4 ; Basisadresse in A4
- ; Kein Test !
- ; Ohne dos.library sind wir eh schon kurz
- ; vorm Absturz :-)
- ; Übrigens: DOS ist die EINZIGE Library,
- ; die ihre Basisadresse beim Aufruf NICHT
- ; in A6 braucht (BCPL's einziger Vorteil)
-
- *** Test auf Workbench oder CLI
-
- tst.l pr_CLI(a5) ; Sind wir vom CLI aus gestartet worden ?
- beq.s WB ; Wenn nicht dann zum WB-Startup
-
- *** CLI-Startup
-
- CLI
- jsr _LVOOutput(a4) ; Handle des CLI-Fensters
- move.l d0,d6 ; in D6
- bra.s main ; und zum Start des Patches
-
- *** WB-Startup
-
- WB
- lea.l pr_MsgPort(a5),a0 ; Sonst auf die Message warten
- jsr _LVOWaitPort(a6) ; die die Workbench sendet
- jsr _LVOGetMsg(a6) ; Sie ist da, wie schön !
- move.l d0,-(a7) ; Zeiger auf Message sichern
- lea fenster(pc),a0 ; Zeiger auf Fenstertitel
- move.l a0,d1 ; in D1
- move.l #MODE_OLDFILE,d2 ; CON: sollte es schon geben
- jsr _LVOOpen(a4) ; öffnen
- tst.l d0 ; hats geklappt ?
- beq.s wbexit ; sonst hats keinen Zweck
- move.l d0,d6 ; Fenster-Handle in D6 sichern
-
- main
-
- *** Länge des Patches ermitteln und in D7 speichern
-
- moveq #endpatch-startpatch,d7 ; Länge unseres Patches
-
- *** Testen, ob wir schon installiert sind
-
- move.l _LVOAllocMem+2(a6),a3 ; Anfangsadresse AllocMem()
- move.l startpatch(pc),a0 ; Start unseres Patches
- cmp.l (a3),a0 ; sind wir schon da ?
- beq.s remove ; dann entfernen
-
- *** Speicher für den Patch reservieren
-
- move.l d7,d0 ; Länge in D0
- moveq #0,d1 ; keine besonderen Anforderungen
- jsr _LVOAllocMem(a6) ; Speicher belegen
-
- *** Speicher bekommen ?
-
- tst.l d0 ; Enthält D0 eine Startadresse ?
- beq.s fehler ; bei 0 haben wir keinen Speicher bekommen
- ; TEST! Speicheranforderungen müssen
- ; immer getestet werden, auch wenn das
- ; System lumpige 16 Bytes eigentlich
- ; finden sollte.
-
- *** Startadresse in A3 zwischenspeichern
-
- move.l d0,a3 ; Adressen immer in Adressregister !
- ; außerdem brauchen wirs noch als Basis
- ; (schau mal ein paar Zeilen tiefer)
-
- *** Den Patch kopieren
-
- lea startpatch(pc),a0 ; Startadresse des Patches in A0
- move.l a3,a1 ; Start reservierter Speicher in A1
- subq #1,d7 ; weil DBRA-Loop
- copyloop ; Kopierschleife
- move.b (a0)+,(a1)+ ; byteweise kopieren
- dbra d7,copyloop ; weil in D7 die Länge in Bytes steht
-
- *** Korrekten ROM-Einsprung für AllocMem in Patch nachtragen
-
- move.l _LVOAllocMem+2(a6),allocmem-startpatch+2(a3)
-
- *** AllocMem() umpatchen
-
- move.l a3,d0 ; Startadresse des Patches
- bsr.s patch
-
- *** Installed-Text ausgeben
-
- lea text1(pc),a0 ; Text-Adresse nach A0
- moveq #text1e-text1,d3 ; Länge in D3
- bsr.s schreibe
-
- *** und aufräumen
-
- bra.s cleanup
-
- *** Hier wird der Patch wieder entfernt
-
- remove
- move.l allocmem-startpatch+2(a3),d0 ; originalen AllocMem-Einsprung holen
- bsr.s patch
-
- *** und der Speicher wieder freigegeben
-
- move.l d7,d0 ; Länge in D0
- move.l a3,a1 ; Startadresse in A1
- jsr _LVOFreeMem(a6) ; D0 Bytes ab A1 freigeben
-
- *** Removed-Text ausgeben
-
- lea text2(pc),a0
- moveq #text2e-text2,d3
- bsr.s schreibe
- bra.s cleanup
-
- *** Fehler-Text ausgeben
-
- fehler
- lea text3(pc),a0
- moveq #text3e-text3,d3
- bsr.s schreibe
-
- *** Falls vom CLI gestartet, sind wir fast fertig
-
- cleanup
- tst.l pr_CLI(a5) ; war es das CLI ?
- bne.s closelib ; dann dos.library schließen
-
- *** Sonst haben wir noch ein bißchen zu tun (WB-Cleanup)
-
- *** Fenster schließen
-
- move.l #150,d1 ; 150/50 (also 3) Sekunden
- jsr _LVODelay(a4) ; warten (damit mans auch lesen kann)
- move.l d6,d1 ; Fenster
- jsr _LVOClose(a4) ; schließen
- wbexit
- bsr.s closelib ; dos-lib schließen
-
- *** Msg beantworten
-
- jsr _LVOForbid(a6) ; Wir wollen nicht zu früh von der WB
- ; rausgeschmissen werden
- move.l (a7)+,a1 ; Die gesicherte msg nach A1
- jmp _LVOReplyMsg(a6) ; und endlich antworten
-
- *** DOS-Lib schließen (erwartet DOSBase in A4 und Exec-Base in A6)
-
- closelib
- move.l a4,a1 ; Dos-Base nach A1
- jmp _LVOCloseLibrary(a6) ; schließen
-
- *** Die Routine zum Patchen von AllocMem() in der Exec-Sprungleiste
- *** wird zweifach aufgerufen, steht darum hier.
-
- patch
- jsr _LVOForbid(a6) ; Multitasking aus (sicher ist sicher)
- move.l #_LVOAllocMem,a0 ; Offset von AllocMem
- move.l a6,a1 ; gepatcht wird in Exec
- jsr _LVOSetFunction(a6) ; und ändern.
- jmp _LVOPermit(a6) ; Multitasking wieder erlauben
-
- *** Text ausgeben (a0 und d3 müssen Adresse und Länge enthalten)
-
- schreibe
- move.l d6,d1
- move.l a0,d2
- jmp _LVOWrite(a4)
-
- *** Hier beginnt der eigentliche Patch
-
- startpatch ; Label für Patch-Startadresse
- btst #17,d1 ; MEMF_LARGEST-Bit testen
- bne.s allocmem ; Bei soviel Hunger MEMF_FAST lieber nicht löschen
- ; (für Kompatibilität mit etlichen NOFASTMEM-Programmen)
- bclr #2,d1 ; sonst MEMF_FAST-Bit löschen
- allocmem
- jmp $12345678 ; diese Adresse wird erst in der Patch-Kopie angepaßt
- ; (sonst wäre FME nicht resident-fähig)
- endpatch ; dient zur Längenermittlung des Patches
-
- *** Dies ist die Text-Sektion
-
- dosname
- dc.b "dos.library",0
- fenster
- dc.b "CON:10/10/320/80/HAL's FastMemEmulator",0
-
- text1
- dc.b "Patch installiert",10
- text1e
-
- text2
- dc.b "Patch entfernt",10
- text2e
-
- text3
- dc.b "Kein Speicher",10
- text3e
-
- END
-