home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
378.lha
/
FME
/
FME.asm
< prev
next >
Wrap
Assembly Source File
|
1990-05-04
|
9KB
|
277 lines
*** 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