“Wäre doch gelacht, wenn ich da nicht noch ein paar Bytes rauskitzeln könnte”, dachte ich mir, als ich mir vornahm, ein bis aufs letzte Byte optimiertes Accessorys zu schreiben, das mir den noch verbleibenden freien Speicherplatz anzeigen sollte.
Irgendwo gab's mal ein RAM-FREE-Programm, das auch nur den freien Restspeicher anzeigte, jedoch eine Länge von 2560 Bytes aufwies und führende Nullen nicht unterdrückte. Das geht besser, dachte ich. Mit ca. 600 Bytes war die erste Version lauffähig, aber bei weitem noch nicht fertig; nun fing die Kleinarbeit erst an:
Datenregister, wenn möglich, mit MOVEQ, Adreßregister mit LEA füllen, Unterroutinen so schieben, daß Kurzadressierung möglich wird (BSRS). Quellen PC-relativ adressieren und Ziele adreßregisterindirekt ansprechen, dabei möglichst auf nicht veränderte Register zurückgreifen. Diese und einige andere auch schon in Ausgabe 7/8 1989 im Artikel Assembler-Optimierung gemachte Möglichkeiten führten dann nach langen Sitzungen zu dem Programm, was Sie unten sehen können. Hinzu kommt die Ausnutzung des Umstandes, daß nicht alle Register bei Systemaufrufen verändert werden. Aber Vorsicht, das gleicht einem Tanz auf dem flochseil und muß bei neueren TOS-Versionen nicht so bleiben.
Interessant dürfte jedoch die Art der Initialisierung sein, wie der Aufruf des AES automatisch die drei Register D7/A5/A6 mit Werten belegt, so daß die Parameter für CONTRL auf effektiv(st)e Weise übergeben werden können. Die Variante mit MOVEP (siehe 1.) zieht hierbei den Kürzeren, funktioniert leider auch nicht auf dem sonst recht guten GFA-Assembler, der hierbei falsche Adreß-Offsets berechnet. Na, und die Dezimalroutine kann sich auch sehen lassen. Sie können sie für eigene Projekte weiterverwenden.
Literatur:
Assembleroptimierung, ST-Computer 7/8 1989
M68000-Familie, W. Hilf / A. Nausch, TeWi Verlag, ISBN 3-921803-16-0
; ******************************
; Ein ganz kurzes Accessory
; 7/89 Jürgen Stessun
; (c) MAXON Computer GmbH
; zeigt freien Speicherplatz an
; ******************************
; Initialisierungsteil fürs ACC
; ******************************
lea STACK(pc),sp ; der Stapel für's ACC
bsr.s FILA6 ; a6 und a5 =CONTRL, d7=1
move.w #10,(a5)+ ; 10 Opcode Appl_Init
move.l d7,(a5)+ ; 0*Intin 1*Intout (d7=1)
clr.w (a5)+ ; 0*Addrin
bsr.s AES ; AES-Aufruf, Register setzen
move.w INTOUT(pc),APPID-CONTRL(a6) ; Appl.-Nummer merken
move.w #35,(a5)+ ; 35 Menu_Register
move.w d7,(a5)+ ; 1*Intin(d7=1)
move.w d7,(a5)+ ; 1*Intout
move.w d7,(a5)+ ; 1*Addrin
move.w APPID(pc),INTIN-CONTRL(a6) ; Applikationsnummer
move.l #ACCNAME,ADDRIN-CONTRL(a6) ; der ACC-Name
bsr.s AES ; AES aufrufen
move.w INTOUT(pc),ACCID-CONTRL(a6) ; die ACC-Nummer
LOOP: bsr.s MEVENT ; auf Ereignis warten
cmpi.w #40,MSGBUFF-CONTRL(a6) ; ACC Open?
bne.s LOOP ; nein, weiter warten
move.w MSGBUFF+8(pc),d0 ; die ACC-Nummer
cmp.w ACCID(pc),d0 ; bin ich gemeint?
bne.s LOOP ; nein, weiter warten
bsr.s MAIN ; ja, Hauptroutine abarbeiten
bra.s LOOP ; und danach wieder warten
MEVENT: move.w #23,(a5)+ ; 23 Evnt_Mesag
move.l d1,(a5)+ ; 0*Intin 1*Intout (d7=1)
move.w d7,(a5)+ ; 1*Addrin
move.l #MSGBUFF,ADDRIN-CONTRL(a6) ; Message-Puffer
; ******************************
; AES aufrufen
; ******************************
AES: move.l #AESPB,d1 ; Zeiger auf Adressliste
clr.w (a5)+ ; 0*Addrout
move.w #$c8,d0 ; Wert für AES
trap #2 ; aufrufen
FILA6: lea CONTRL(pc),a6 ; Zeiger für A6
movea.l a6,a5 ; und A5
moveq.l #1,d7 ; d7 auf 1 setzen
rts ; fertig mit AES
; ***************************
; Der eigentliche Aktionsteil
; ***************************
MAIN: moveq.l #-1,d0 ; Restspeicher erfragen
move.l d0,-(sp) ; -1.L auf Stack
move.w #$48,-(sp) ; MALLOC
trap #1 ; Gemdos
addq.l #6,sp ; in D0 Restspeicher
lea NUMMER(pc),a4 ; Stringadresse in Alert
PRLONG: bsr.s LONGNUM ; in Dezimal wandeln
move.l #ALTEXT,ADDRIN-CONTRL(a6) ; Text für Alarmbox
ALERT: move.w #52,(a5)+ ; 52 Form Alert
move.w d7,(a5)+ ; 1*Intin(d7=l)
move.w d7,(a5)+ ; 1*Intout
move.w d7,(a5)+ ; 1*Addrin
move.w d7,INTIN-CONTRL(a6) ; Default Button = 1
bra.s AES
; ******************************
; Die Dezimal-Umwandlungsroutine
; ******************************
LONGNUM: moveq.l #7,d4 ; insgesamt 7 Stellen
move.l #1000,d1 ; zuerst 4-stellig
moveq.l #(' '-'0'),d2 ; Space erlaubt
divu.w d1,d0 ; durch 1000
bsr.s D4TODEZ ; umwandeln
swap.w d0 ; Rest in d0.w
moveq.l #100,d1 ; dann 3-stellig
D4TODEZ: move.w d0,d3 ; Zahl retten
W1: ext.l d3 ; auf Lang erweitern
subq.w #1,d4 ; schon letzte Ziffer?
bne.s W2 ; nein
clr.w d2 ; sonst kein Space erlaubt
W2: divu.w d1,d3 ; Rest durch Teiler
beq.s DEZPR1 ; ergab schon 0
clr.w d2 ; kein Space erlaubt
DEZPR1: add.b d2,d3 ; Offset zu Space addieren
addi.b #'0',d3 ; Offset für ASCII
move.b d3,(a4)+ ; ablegen in String
swap.w d3 ; Rest der Division
divu.w #10,d1 ; nächster Teiler
bne.s W1 ; wenn ungleich 0
rts ; sonst fertig
.DATA
ACCNAME: .DC.b ' Memory',0 ; 2 Spaces vor 'Me...'
ALTEXT: .DC.b '[0][Memory:'
NUMMER: .DC.b ' Bytes ' ; 8 Spaces vor 'By...'
.DC.b '][Ok]',0
.EVEN
AESPB: .DC.l CONTRL,GLOBAL,INTIN,INTOUT,ADDRIN,ADDROUT
.BSS
APPID: .DS.w 1 ; die Applikationsnummer
ACCID: .DS.w 1 ; die ACC-Nummer
MSGBUFF: .DS.b 16 ; der Nachrichtenpuffer
CONTRL: .DS.w 1 ; Opcode der AES-Funktion
.DS.w 1 ; Anzahl der Intin-Einträge
.DS.w 1 ; Anzahl der Intout-Ausgaben
.DS.w 1 ; Anzahl der Addrin-Einträge
.DS.w 1 ; Anzahl der Addrout-Ausgaben
GLOBAL: .DS.w 15
INTIN: .DS.w 2 ; Wort-Eingaben
INTOUT: .DS.w 2 ; Wort-Ausgaben
ADDRIN: .DS.1 2 ; Adreß-Eingaben
ADDROUT: .DS.l 2 ; Adreß-Ausgaben
.DS.b 100 ; Platz für Stapel
STACK:
.END
a$=SPACE$(320)
adr%=VARPTR(a$)
RESTORE daten
CLR pruef%
FOR n%=0 TO 79
READ b$
wert%=VAL("&H"+b$)
LPOKE adr%+4*n%,wert%
pruef%=pruef% XOR (wert%)
NEXT n%
IF pruef%<>&H73DF00B4
ALERT 1," Daten nicht korrekt | Bitte überprüfen",1,"OK",dummy%
ELSE
BSAVE "MEMORY.ACC",adr%,318
ALERT 1," Alles Ok ",1,"Ende",dummy%
ENDIF
EDIT
daten:
DATA 601A0000,D40000,400000,B80000,0,0,0,4FFA01CA,61663AFC
DATA A2AC7,425D614E,3D7A0142,FFEC3AFC,233AC7,3AC73AC7
DATA 3D7A00F2,282D7C,D4,30612E,3D7A0122,FFEE6116,C6E0028
DATA FFF066F6,303A00DE,B07A00D0,66EC612A,60E83AFC,172AC7
DATA 3AC72D7C,118,30223C,FC,425D303C,C84E42,4DFA00BA,2A4E7E01
DATA 4E7570FF,2F003F3C,484E41,5C8F49FA,646118,2D7C0000,DD0030
DATA 3AFC0034,3AC73AC7,3AC73D47,2860BE,7807223C,3E8,74F080C1
DATA 61044840,72643600,48C35344,66024242,86C16702,4242D602
DATA 6030030,18C34843,82FC000A,66E24E75,20204D65,6D6F7279,5B305D
DATA 5B4D656D,6F72793A,20202020,20202020,42797465,73205D5B
DATA 4F6B5D00,128,132,150,154,158,160,28,30082A72,4040404
DATA 4000000 ! 320 Bytes=80 Data