amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Suche [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- 2 3 4 Ergebnisse der Suche: 108 Treffer (30 pro Seite)
jolo   Nutzer

19.11.2019, 21:56 Uhr

[ - Direktlink - ]
Thema: Anfängerfrage: Wieso sind OpenLibrary und OpenDevice unterschiedlich?
Brett: Programmierung

Früher konnte ich nicht antworten, weil der Broterwerb im Wege steht...

Egal.

Zitat:
Original von Holger:
Zitat:
Original von jolo:
Beim Aufruf, von z.B. AllocVec() der Exec-Library musst Du die absolute Adresse des Sprungziels ermitteln und dann anspringen:

code:
AllocVec  EQU  -684  ; wie beschrieben, negativ und in 6-Byte
                     ; Schritten - zeigt auf "JMP ABSOLUTE ADRESSE"
                     ; - siehe oben

     movea.l _SysBase,A6
     adda.w  #AllocVec,A6
     jsr     0(A6)


Bitte?!
Seit wann rufen wir library Funktionen mit etwas anderem als der Basisadresse der library in A6 auf?
[/code]


Erst nach zweimaligen Lesen Deines Einwandes verstehe ich jetzt worauf Du hinaus willst.
Da nur ein absolutes Sprungziel ermittelt werden musste um den dortigen Code auszuführen, kann irgendein Register (A0-A6) Verwendung finden.
Würde man die Funktion zum Allokieren von Speicher aber wirklich so aufrufen, also unter Missachtung der Amiga-m68k-ABI, ist ein Software-Error nicht mehr fern.
Die Verwendung von A6 ist hier tatsächlich unglücklich von mir gewählt; hier hätte ich besser ein anderes Register nehmen sollen.
Ich war mir dessen gar nicht bewusst, weil es für mich nur darum ging, die Abarbeitung ab "JMP ABSOLUTE ADRESSE" zu bestimmen und nicht wirklich AllocVec() aufzurufen.


Zitat:
Zitat:
Für Hochsprachen wie C verschleiert die Amiga-API durch INLINE- oder GLUE-Code, dass zu einem Funktionsaufruf immer der Basis-Zeiger benötigt wird:
code:
mem = AllocVec( 4096, 65536); /* 65536 = MEMF_CLEAR */


Tatsächlich wird aber ein:
code:
mem = SysBase->AllocVec( 4096, 65536);

ausgeführt.

Da aber negative Offsets von Hochsprachen aus nicht ganz unproblematisch sind, wie auch die 6er Schritte zur Bestimmung des Sprungziels, hat man das in 68k Assembler gekapselt, was zur besagten Notation ohne Basis-Zeiger führt.

Das halt vor allem auch damit zu tun, dass SysBase->AllocVec( 4096, 65536); niemals zu einem jsr AllocVec(A6) compiliert werden würde und es auch keinerlei Konstrukt im C-Standard gibt, das den gewünschten Code erzeugen würde. Wie bereits oben erwähnt, reicht es eben nicht, die Zieladresse zu ermitteln, der Standard schreibt auch vor, dass die Basisadresse im Register A6 übergeben wird.

Sag' niemals nie.
Allerdings hast Du recht; momentan gibt es kein C-Sprachgerüst, welches die Amiga-m68k-ABI unterstützt.


Zitat:
Deshalb braucht man #pragma, inline Assembler oder eine Linkbibliothek, die den gewünschten Code in vorgefertigter Form enthält.

Nicht unbedingt. Mit ein bisschen Aufwand ist es mit modernen C/C++ Compilern ohne Probleme möglich, siehe Beispiel.
Wie man sieht, sogar nur mit Bordmitteln.
Aber so effektiv wie INLINE-Code ist es natürlich nicht. :-)
Da bleibe ich lieber bei INLINE-Code.

Trotzdem, mit jedem X-beliebigen C/C++ Compiler kann man selbst den Self-Pointer für m68k (A6) auch schön verschleiern (siehe Makro im Beispiel), so dass wir wieder beim Verstecken von Pointern sind, was bei Nichtbewanderten der Amiga-API/ABI zu Kopfschmerzen führen könnte.
Aber, als in den 80er Jahren des letzten Jahrhunderts die Amiga-m68k-ABI spezifiziert wurde, konnte kein C-Compiler Argumente in explizite CPU-Register platzieren, nicht einmal der Green Hills C Compiler. Das musste händisch nachgerüstet werden.
Ergo, erst heute könnten wir das so machen; nicht in den 80er des letzten Jahrhunderts.

code:
extern void *LVOWrite;	/* amiga oder small lib */
extern void *LVOOutput;

extern void *DOSBase;

#ifndef REG
 #ifdef __VBCC__
  #define REG( reg, arg) __reg(#reg) arg
 #endif

 #ifdef __GNUC__
  #define REG( reg, arg) arg __asm(#reg)
 #endif

 #ifdef __MAXON__
  #define REG( reg, arg) register __##reg arg
 #endif
#endif

struct DOS {
	long (*IWrite)( REG(a6, void *),
				    REG(d1, long stream),
				    REG(d2, char *buffer),
				    REG(d3, long length));
	long (*IOutput)( REG(a6, void *));
};

struct DOS Idos;
struct DOS *IDOS = &Idos;


#define Write( s, b, l) IWrite( DOSBase, (s), (b), (l))
#define Output() IOutput( DOSBase)


int main( int argc, char **argv)
{
	IDOS->IWrite = (long (*)( REG(a6, void *),
				    REG(d1, long stream),
				    REG(d2, char *buffer),
				    REG(d3, long length)))
				   ((long) DOSBase + (long) &LVOWrite);
	IDOS->IOutput = (long (*)( REG(a6, void *)))
				   ((long) DOSBase + (long) &LVOOutput);


	IDOS->Write( IDOS->Output(), "Hello World!\n", 13);
}


Zitat:
In AmigaOS 4 sieht das ganze dagegen ganz anders aus.

Na ja, so viel Unterschied sehe ich da jetzt nicht. Das Konzept ist eigentlich immer noch das Gleiche, auch wenn jetzt mehrere Interfaces unterstützt werden und es C/C++ freundlicher ausgelegt wurde (nicht beim Erstellen, sondern beim Benutzen). Der Aufwand, eine AmigaOS4 Bibliothek zu erstellen ist um ein Vielfaches umfangreicher als eine Bibliothek unter OS1 bis OS3, weil eine gänzlich andere ABI zugrunde liegt.
Man hätte das auch in den 80er Jahren des letzten Jahrhunderts schon annähernd machen können, falls a) der Compiler dies unterstützt hätte, b) mehr CPU-Register zur Verfügung gestanden hätten, c) eine ähnliche ABI wie beim PPC als Grundlage herangezogen wäre, d) die Rechenleistung höher gewesen wäre.
Ich weiß, hätte, hätte, Fahrradkette...


Zitat:
Abgesehen von den internen Details, rufst Du eben Funktionen der geöffneten Bibliothek auf, während Du bei Devices weiterhin Funktionen von Exec aufrufst.

Zitat:
DoIO() und SendIO() sind nur Exec Container-Funktionen, die aber auch immer BeginIO() des Geräts bemühen müssen.

Ändert aber nichts daran, dass die Anwendung nicht die Basisadresse des Devices, sondern die der exec.library in A6 zur Verfügung stellen muss, wenn sie diese Exec Funktionen aufruft. Außerdem macht z.B. DoIO() schon ein bisschen mehr, wie z.B. Warten, wenn das device keine synchrone Ausführung beherrscht.


Richtig.
Wenn ich spekulieren müsste, würde ich sagen, dass DoIO() und SendIO() eigentlich nur wegen des ursprünglichen DOS in Exec aufgenommen wurden, damit das DOS Zugriff auf das Serial-, Timer- und TrackDisk-Device bekommt; DoIO() macht ja nichts anderes als BeginIO() mit gesetzter IOF_QUICK-Flagge aufzurufen und je nachdem was der Gerätetreiber unterstützt, entweder im Kontext des aufrufenden Programms alles abzuarbeiten oder, falls das nicht möglich ist, WaitIO() zu bemühen um dann letztendlich die Nachricht aus der Nachrichten-Queue zu entfernen, während SendIO() nur BeginIO() mit gelöschter IOF_QUICK-Flagge aufruft, wobei DoIO() und SendIO() so ihre Tücken haben, weil sie unter Umständen die Flaggen des IORequest nach einem Funktionsaufruf überschreiben.
Zudem, die Möglichkeit die IOF_QUICK-Flagge zu setzen um schnellstmöglich wieder zum normalen Programmablauf zurück zu kehren, wobei die Ausführung länger dauert als erwartet, also die IOF_QUICK-Flagge seitens des Gerätertreibers gelöscht wird, und statt dessen ein anderer Task/Prozess die Arbeit übernimmt, wird nicht von DoIO()/SendIO() abgedeckt; das geht nur direkt über BeginIO().
Aber zurück, wie gesagt Spekulation, weil es zwei Funktionen im BCPL verfassten DOS mit gleichen Namen gibt (doIO() #13?, sendIO() #14?), wobei ein direkter Aufruf von BeginIO() unter BCPL nicht funktionieren kann, weil Adressen in BCPL immer Langwort-Indexe sind und nicht nur an geraden Adressen ausgerichtet sein müssen.
Falls ich mal Zeit finde, disassembliere ich die beiden BCPL Funktionen.


@Reth
Tue Dir selber einen Gefallen und setzte nach dem Öffnen irgendeines Devices manuell den Typ der Nachricht deines MsgPorts auf NT_REPLYMSG. CheckIO() dankt es dir.

iorequest.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
oder fürs Timer-Device
timerio->tr_node.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
 
jolo   Nutzer

12.11.2019, 21:30 Uhr

[ - Direktlink - ]
Thema: Anfängerfrage: Wieso sind OpenLibrary und OpenDevice unterschiedlich?
Brett: Programmierung

Die negativen Offsets einer Bibliothek (Library) verweisen auf absoluten Code, der so aufgebaut ist:

code:
Offset_Minus_36
   jmp _ByeBye
Offset_Minus_30
   jmp _Aloha
Offset_Minus_24
   jmp _Reserved
Offset_Minus_18
   jmp _Expunge
Offset_Minus_12
   jmp _Close
Offset_Minus_6
   jmp _Open
LibraryBasePointer ; (Offset 0)


Da "JMP" mit einer absoluten Adresse 6 Bytes belegt, sind die Offsets immer in Schritten von -6 Bytes von der Basisadresse entfernt.

Die ersten 4 Sprungziele (Open, Close, Expunge und Reserved) sind für alle Bibliotheken (Libraries) und Gerätetreiber (Devices) in dieser Anordnung zu implementieren, weil bei einem Aufruf von OpenLibrary() / OpenDevice() die Funktion "_Open" durchlaufen werden muss, beim Schließen der Bibliothek / Gerätetreiber "_Close". Somit müssen die ersten vier Sprungziele ein verbindliches Verhalten aufweisen, damit die Handhabung von Bibliotheken und Gerätetreibern von Exec aus bewerkstelligt werden kann.

Gerätetreiber bauen auf Bibliotheken auf, wobei aber die ersten *6* Sprungziele verbindlich sind:

code:
Offset_Minus_36
   jmp _AbortIO
Offset_Minus_30
   jmp _BeginIO
Offset_Minus_24
   jmp _Reserved
Offset_Minus_18
   jmp _Expunge
Offset_Minus_12
   jmp _Close
Offset_Minus_6
   jmp _Open
DeviceBasePointer ; (Offset 0)


Beim Aufruf, von z.B. AllocVec() der Exec-Library musst Du die absolute Adresse des Sprungziels ermitteln und dann anspringen:

code:
AllocVec  EQU  -684  ; wie beschrieben, negativ und in 6-Byte
                     ; Schritten - zeigt auf "JMP ABSOLUTE ADRESSE"
                     ; - siehe oben

     movea.l _SysBase,A6
     adda.w  #AllocVec,A6
     jsr     0(A6)


oder einfacher:

code:
     movea.l _SysBase,A6  ; A6 = z.B: $40000810 - Basis Exec
     jsr     AllocVec(A6) ; = -684(A6) == $40000564


In anderen Worten, springe zur Adresse $40000564 und mache da weiter (ergo AllocVec() ausführen).

BeginIO() wird nicht anders aufgerufen:
code:
     movea.l _IORequest,A1
     movea.l 20(A1),A6    ; io_Device(A1),A6 - Geräte-Basis-Zeiger
                          ; aus IORequest Datensatz
     jsr     -30(A6)      ; Aufruf von BeginIO des betreffenden Geräts


Für Hochsprachen wie C verschleiert die Amiga-API durch INLINE- oder GLUE-Code, dass zu einem Funktionsaufruf immer der Basis-Zeiger benötigt wird:
code:
mem = AllocVec( 4096, 65536); /* 65536 = MEMF_CLEAR */


Tatsächlich wird aber ein:
code:
mem = SysBase->AllocVec( 4096, 65536);

ausgeführt.

Da aber negative Offsets von Hochsprachen aus nicht ganz unproblematisch sind, wie auch die 6er Schritte zur Bestimmung des Sprungziels, hat man das in 68k Assembler gekapselt, was zur besagten Notation ohne Basis-Zeiger führt.


Zitat:
Abgesehen von den internen Details, rufst Du eben Funktionen der geöffneten Bibliothek auf, während Du bei Devices weiterhin Funktionen von Exec aufrufst.

DoIO() und SendIO() sind nur Exec Container-Funktionen, die aber auch immer BeginIO() des Geräts bemühen müssen.
 
jolo   Nutzer

11.11.2019, 21:12 Uhr

[ - Direktlink - ]
Thema: Anfängerfrage: Wieso sind OpenLibrary und OpenDevice unterschiedlich?
Brett: Programmierung

Die Antwort hat Holger eigentlich schon gegeben:

Zitat:
Der Basiszeiger wird ja nicht (direkt) benutzt, wenn Du die I/O Funktionen aufrufst, sondern Du rufst Exec Funktionen mit der IORequest Struktur als Argument auf.

Zur Verdeutlichung:

Bei OpenLibrary() wird Dir die Basisadresse zu einer bestehenden oder gerade geöffneten Bibliothek retourniert, oder null, falls es diese Bibliothek nicht gibt; bei OpenDevice() erstellst Du die individuellen Datensätze selber (IORequests), welche für unterschiedliche Geräte unterschiedlich groß sind, die Du wiederum vorher zu initialisieren hast - inklusive MessagePort -, um dann anzufragen, ob dieser Datensatz (dein erstellter IORequest) so vom Gerätetreiber akzeptiert wird, denn, unter Umständen kann die zugrundeliegende Hardware nicht von mehreren Tasks/Prozessen gleichzeitig benutzt werden (audio, timer etc. - je nach verwendeter Komponente), also wird ein Fehlercode retourniert, falls dein Gesuch so nicht akzeptiert werden konnte.
Das Gerät selber, also z.B. "audio", "trackdisk" oder "timer" wird in den meisten Fällen vorhanden sein, aber je nachdem welche Aktionen Du durchführen möchtest, könnte es zu Überschneidungen mit anderen Programmen führen, welche die gleiche Aktion derzeit tätigen, die Du beabsichtigst. Also stellt OpenDevice() eigentlich nur sicher, dass es keine Überschneidungen gibt, und dafür wird ein initialisierter Datensatz (IORequest) benötigt, der Dir *und* dem Gerätetreiber als Basis dient, und nicht der Device-Zeiger selber.
Ein einzelnes Gerät kann mehrere Komponenten aufweisen (audio device = min. 4 Kanäle (= 4 Komponenten)). Ein einzelner Zeiger deckt dies nicht ab.

Zudem, OpenLibrary() initiiert keinen neuen Task/Prozess, sondern Du benutzt Routinen (Library Vectors), die einmal im Speicher vorhanden, sofort ausgeführt werden können (relativ zur Basisadresse) im Kontext deines eigenen Tasks/Prozesses.
Bei IORequests sieht das aber gänzlich anders aus: Unter Umständen schiebst Du nur eine Anfrage an den Gerätetreiber rüber (BeginIO()), wobei das Gesuch (IORequest) selber in der Größe zu anderen Gerätetreiber differieren kann, und zudem noch von einem anderen Task/Prozess ausgeführt werden muss, welcher vom Device selber erstellt wurde (siehe Beitrag von 68kassembler).

Library = Sammlung von Routinen ohne Hardware-Relevanz, welche synchron ausgeführt werden.
Device = Funktionen eines Gerätetreibers, die zumeist asynchron ausgeführt werden, mit unterschiedlichen Größen der Datensätze (IORequests) - abhängig vom Device - für unterschiedliche Komponenten (Unit) des Geräts (Device).

Der Funktionsname OpenDevice() der Exec-Library ist kurz und prägnant aber in Bezug auf seine Funktionalität nicht wirklich eindeutig gewählt, weil man nicht nur einen Gerätetreiber öffnen kann, sondern gleich beim Öffnen auch erfragen kann, ob eine Komponente (Unit) des Geräts (Device), abhängig von dem spezifizierten Datensatz (IORequest), für eigene Zwecke nutzbar ist, wobei die Basisadresse immer Dein IORequest ist und nicht der Device-Zeiger, denn Standard-Devices bieten nur zwei Funktionen an, die wie bei einer gewöhnlichen Library angeordnet sind: BeginIO() = Offset -30 und AbortIO() = Offset -36, ergo wird die Basisadresse des Geräts nur zum Ermitteln des Sprungzieles gebraucht - der Datensatz (IORequest) aber zum Ansprechen der Hardware-Komponente.

OpenDevice() entspricht somit einem "Zugriff auf Komponente X des Geräts Y erlaubt?" und nicht nur "Öffne Gerät". Dass man da halt einen Fehlercode retourniert finde ich passend und wohlüberlegt.
 
jolo   Nutzer

23.09.2019, 12:21 Uhr

[ - Direktlink - ]
Thema: Bild aus struct Image + UWORD *ImageData in Malprogramm laden - wie?
Brett: Amiga, AmigaOS 4

@Reth

Da Du ein 16-Bit-Array hast (ich hoffe in Form eines Quellcodes!), hast Du schon einmal die Daten, also müsste ein RAW-Loader die Grafik unter Falschfarben schon darstellen können, sofern die Breite als Mehrfaches von 16 von Dir spezifiziert wurde und "PlaneOnOff" nicht benutzt wurde.

Breite (in Pixels) PLUS 15 AND -16 = tatsächliche Breite (mehrfaches von 16 ('WORD aligned'))
Höhe, bleibt Höhe

Beispiel:

(49 Pixels + 15) & -16 = 64 (tatsächliche Breite)

In der Shell kann man das kurz errechnen:

1> eval 49 + 15 & -16

Da ein "Image" nichts über Farben aussagt, musst Du aber im Programm nachschauen, welche Farben benutzt wurden.

Ein "Image" ist meist aber ein platzsparendes Format, in welchen nur Daten einfließen, die für eine gesamte "Bitplane" nicht null oder eins sind.

Bei einem einfarbigen "Image" wäre "PlanePick" 1 und "PlaneOnOff" 0, bei einem zweifarbigen "Image" aber "PlanePick" 3 und "PlaneOnOff" 0, sofern Du alle vier Farbstifte für die Grafik verwendest. Verwendest Du aber nur die Farbstifte eins und drei, dann wäre "PlanePick" 2 und "PlaneOnOff" 1, wobei nur eine "Bitplane" durch "ImageData" abgedeckt werden müsste.

PlanePick = 2 (Daten für Bitplane 1 (%10) kommen aus "ImageData", Daten für "Bitplane" 0 (%01) sind nicht spezifiziert)
PlaneOnOff = 1 (setze alle Bits der "Bitplane" 0 (%01) auf eins)

heißt, eine 2 "Bitplane" aka 4 Farb-Grafik, wobei alle Bits der "Bitplane" 0 auf eins gesetzt werden, und nur "Bitplane" 1 die eigentlichen Daten enthält (Bit in "PlanePick" ist gesetzt aber Bit in "PlaneOnOff" gelöscht, so dass hier die tatsächlichen Daten aus "ImageData" gelesen werden müssen).

Für eine 8-Farben-Grafik, wobei alle Daten aus "ImageData" entnommen werden müssten, würde
PlanePick : 7 (%111) ("Bitplane 2, 1 und 0 gesetzt)
PlaneOnOff : 0 (%000) (keine einzige "Bitplane" von vornherein eingefärbt)
sein.


Für AdPro müsstest Du die "ImageData" Daten aber ohne die "Image Struct" als Binärformat aufbereiten, anhand von "PlanePick" und "PlaneOnOff", und dann sichern um diese dann wiederum als RAW einladen.

Ich würde aber vorschlagen, ein Programm zu schreiben, das die ASCII-Daten ausliest und als "Brush" speichert - inklusive fest verankerter Farben des Programms - ist einfacher.

Noch einfacher ist es aber, das Programm zu kompilieren und auszuführen um dann mittels AdPro die Grafik aus dem laufenden Programm zu übernehmen (Screenshot) - also die Dummy-Methode, wie von Thomas vorgeschlagen.

Anbei, Thomas, bist Du auf "PlanePick/PlaneOnOff" in Deinem Beispiel eingegangen?
Ich habe schon häufiger Quelltexte gesehen, die immer nur anhand von "Image Depth" die Daten speicherten, was oft nur Müll ergibt.


Grüße
 
jolo   Nutzer

14.09.2019, 14:53 Uhr

[ - Direktlink - ]
Thema: WinUAE und Tastaturbelegung (mal wieder...)
Brett: AROS und Amiga-Emulatoren

@Reth:

Ich benutze die linke Windows-Taste selten, so dass mir gar nicht aufgefallen ist, dass man heutzutage unter Windows 10 von Seiten WinUAE gar nicht mehr LWIN + V, LWIN + G sowie LWIN + L abfangen kann... Mein Fehler.
Wenn Du wirklich die linke Windows-Taste verwenden willst, kannst Du mittels SharpKeys (https://www.randyrants.com/category/sharpkeys/) diese umlegen oder die Registry entsprechend ändern.
Ich würde aber empfehlen, eine andere Taste auf der rechten Seiten der Leertaste zu benutzen.

Microsoft hat das Problem wohl selber auch erkannt und für Gamer die Datei MicrosoftFixit50465.msi erstellt; diese deaktiviert die Taste aber komplett, was Dir nichts nützt.

Wenn Du weiterhin die linke Windows Taste in WinUAE abfragen willst, bleibt nur der Umweg über die Registry oder SharpKeys; ich würde dann aber SharpKeys bevorzugen.


Grüße
 
jolo   Nutzer

14.09.2019, 10:09 Uhr

[ - Direktlink - ]
Thema: WinUAE und Tastaturbelegung (mal wieder...)
Brett: AROS und Amiga-Emulatoren

@Reth:

Ich verwende so einen Quatsch wie die cloudbasierte Zwischenablage für Windows 10 nicht, weil ich meine Daten bestimmt nicht weltweit durch die Gegend schieben will.

Schalte die cloudbasierte Zwischenanlage mal aus:

Start > Einstellungen > System > Zwischenablage

Einschalten kannst Du diese immer nach dem Hochfahren des Rechners ohne den Umweg über die Einstellungen zu nehmen, indem Du WIN+V drückst. Dann erscheint eine Nachricht, ob diese eingeschaltet werden soll. Funktioniert auch, falls Du noch von anderen Clients gerade Daten in der cloudbasierte Zwischenablage hast. Mit wie vielen Geräten bist Du denn eigentlich in der Cloud unterwegs?

Weiterhin solltest Du überprüfen, ob Du im BIOS/UEFI keine Option findest, um das normale Tastatur-Layout verwenden zu können. Dann jedoch wechselst Du auf spezielle Funktionen, wie z.B. den Flugmodus, nur noch über "Fn + F12". Wäre mir persönlich aber lieber.

Da HP sehr speziell zu sein scheint, musst Du mal in der Anleitung nachschauen, wie Du den Boot-Prozess stoppen kannst (F10?), um in das BIOS/UEFI zu gelangen. Standard ist eigentlich ENTF oder F8, aber das ist bei HP garantiert geändert... Ich meine mich zu erinnern, dass dies in der Vergangenheit nur über F10 klappte, kann mich aber auch täuschen.


Grüße
 
jolo   Nutzer

07.09.2019, 11:17 Uhr

[ - Direktlink - ]
Thema: WinUAE und Tastaturbelegung (mal wieder...)
Brett: AROS und Amiga-Emulatoren

WinUAE mit der entsprechenden Amiga-Konfig starten.

Nachdem WinUAE in die Workbench gebootet hat, F12 drücken.

"Config 1" und "WinUAE Keybord" auswählen.

"Test"-Button anklicken.

Taste, deren Tastenbelegung geändert werden soll, drücken.

WInUAE scrollt und hinterlegt die aktuell gedrückte Taste.

Diese Tastenbezeichnung (1. Spalte) merken.

Taste, die anstelle der originalen Taste Verwendung finden soll, drücken.

Deren Tastenbelegung (2. Spalte) merken. Normalerweise sollte beim Drücken der Taste rechts neben "Alt Gr" die Zuweisung "Right Amiga" stehen (also bei Dir beim Drücken von "<").

F12 drücken (Konfig kann jetzt wieder normal benutzt werden).

Die Tastenzuweisung (1.Spalte) suchen und anklicken.

Du siehst, dass sich neben dem Test-Button der Inhalt des Gadgets unterhalb des Auswahlbereiches verändert. Linksklick drauf und ein Pop-Up-Menü erscheint. Auswahl tätigen, also auf den Wert stellen, den Du Dir in der 2.Spalte gemerkt hast.

Konig speichern, fertig.

Standard Zuweisung für "<"
1.Spalte.........2.Spalte
OEM_102 [0x56]...Keycode 0x30

Standard Zuweisung für "Apps" (Taste rechts neben "Alt Gr")
1.Spalte.........2.Spalte
Apps [0xDD]......Right Amiga

Anbei, im Gegensatz zu Dir, verändere ich das Tastatur-Layout immer entsprechend der Aufdrucke der Tasten. Irgendwo auf Deiner Laptop-Tastatur muss sich die "Apps"-Taste befinden (Viereck mit drei horizontalen Strichen darin). Diese würde ich suchen und die Belegung auf "Right Amiga" ändern.
Gleiches gilt für die Windows-Taste ("LWIN" [0xDB]). Diese suchen und den Wert auf "Left Amiga" ändern.
Ich halte nichts davon, die Aufdrucke einer Tastatur zu ignorieren, was mich persönlich nur irritieren würde. Selbst wenn ich nur über eine eingeschränkte Laptop-Tastatur verfügen würde, welche Sondertasten nur mittels einer Kombination aus "Fn + TASTE" preisgibt, würde ich diese in WinUAE suchen und entsprechend meinen Bedürfnissen konfigurieren (siehe oben).
Z.B. gibt es "Einfg" bei meinem Laptop nur mittels "Fn"-Taste in Verbindung mit der "Entf"-Taste.
Das kann ich leicht in WinUAE abfragen und entsprechend meinen Bedürfnissen in der Konfig speichern, so dass ich diese wie unter Windows auch benutzen kann (sofern es der Texteditor unter AmigaOS unterstützt).

Leider werden manche Tasten seitens Windows nur als US-Version durchgereicht (z.B. wird das Doppelkreuz als Backslash interpretiert; da habe ich mir halt unter AmigaOS ein eigenes PC-Tastatur-Layout geschaffen, das diese Tasten entsprechend der Amiga-Bedürfnisse ummünzt.
WinUAE kann da nichts für; Windows ist ziemlich eingeschränkt, was Tastatur-Layouts angeht. Deshalb sollte man auch unter AmigaOS erst einmal die Keymap auf was Brauchbares ändern, z.B. "uae_german", bevor man überhaupt anfängt, das WinUAE-Tastatur-Layout zu ändern.

Grüße
 
jolo   Nutzer

09.07.2018, 19:27 Uhr

[ - Direktlink - ]
Thema: Global Vektor
Brett: Programmierung

@wawa:
BCPL kompilierte Programme befinden sich im C:-Verzeichnis der Workbench Diskette.
Allerdings gibt es auch da einige, die in C verfasst wurden, z.B. SetClock, oder einen Mix aus Assembler und BCPL benutzten, siehe Ed.
List, Dir, Install, Join, Delete usw. sind BCPL kompiliert. Du kannst das daran erkennen, dass der Startup-Code 316 Bytes groß ist und jedes BCPL kompiliertes Objekt nur aus zwei Code-Hunks besteht, Position-unabhängig geschrieben wurde und die Objekt-Datei recht klein ist. Oder Du benutzt das Fragezeichen nach dem Kommandonamen, steht dann da ein Template, ist es in BCPL geschrieben, z.B. "Ask ?" -> "PROMPT/A:".

Aber wie schon einmal gesagt, solange das DOS nicht ab 0xFC0000 eingeblendet wird, geht das ganze Unterfangen schief, egal ob AROS korrekt die Funktionen nachbildet. Unter Umständen verwenden CLI Programme GOTOs anstatt Funktionen des globalen Vektors, die anhand einer festen Distanz relativ zum Inhalt des Register A4 aufgerufen wurden. Hier braucht es das originale ROM, weil sich Abstände zu Instruktionen nicht ändern dürfen (alte Funktionsadresse + feste Distanz = GOTO-Adresse).

Wie schon einmal gesagt, das Ganze besser einfach vergessen, da Funktionen die über den globalen Vektor erreicht wurden, eh nicht zur offiziellen API gehörten.

Grüße

--
Stupid mistakes are always made by others -
we only make unavoidable errors
 
jolo   Nutzer

04.07.2018, 21:45 Uhr

[ - Direktlink - ]
Thema: Global Vektor
Brett: Programmierung

@wawa:
Wirklich, man braucht den ganzen Kram heutzutage nicht mehr. Ich hab ja auch nur nach den Bezeichnern gefragt, bzw. ob evtl. jemand da etwas halb-offizielles in petto hätte.

Der globale Vektor unter Kickstart 1.x wird ja nur darum verwendet, weil BCPL keinen Linker einsetzte, sondern Module als Segmente eines Programms betrachtete, ergo mussten irgendwo diese globalen Funktionen seitens der Module (Segmente) bereitgestellt, um letztendlich dem Programm zugänglich gemacht zu werden. Also ist ein globaler Vektor unter BCPL nichts weiter als eine Krücke für den fehlenden Linker, über den sich die Segmente austauschen, wobei das Programm selber auch nur ein weiteres Segment ist.

Das Ganze ist aber auch nicht soooo einfach wie es sich anhört, sondern basiert auf BCPL-Richtlinien, die irgendwann in den 60er Jahren des letzten Jahrhunderts spezifiziert wurden. Demnach muss der "BCPL Loader" ein Haufen Arbeit übernehmen, damit BCPL-Programme überhaupt gestartet werden können (globalen Vektor erstellen, Segmente laden (falls diese weder im ROM noch RAM gefunden wurden) damit diese sich in den bereitgestellten globalen Vektor eintragen können, dann das eigentliche Programm laden und dieses den globalen Vektor bekannt machen; schauen welche Initialisierung seitens des Programmes gewünscht wird und vieles mehr).

Wir benutzen dafür heutzutage einen linearen, geraden Weg und entweder statische Linker-Bibliotheken oder Betriebssystemfunktionen in sogenannten Shared-Libraries, was bedeutend einfacher ist.

Um AROS Kickstart 1.x Kompatibilität beizubringen, müsste erst einmal der BCPL-Loader geschrieben und alle DOS-Segmente ins BCPL-Modul-Format konvertiert werden, scheitert dann aber trotzdem, weil das ROM zwingend ab 0xFC0000 im Speicher eingeblendet werden müsste, weil BCPL-Segment-Initialisierung Stunts benutzt, um herauszufinden, ob Segmente im ROM oder RAM liegen. Und das ist nicht das einzige Kunststück, das sich das AmigaDOS der alten Schule leistet, ganz zu schweigen von den CLI-Kommandos der ersten Stunde...

Fazit: Nicht über eine Neuimplementierung nachdenken und abhaken.

--
Stupid mistakes are always made by others -
we only make unavoidable errors
 
jolo   Nutzer

27.06.2018, 19:56 Uhr

[ - Direktlink - ]
Thema: Global Vektor
Brett: Programmierung

@o1i:

Ich sehe keinen Bedarf der AROS-Entwickler dort nachzubessern; keiner verwendet heutzutage noch diesen globalen Vektor ( außer den OS1.2/1.3 CLI-Kommandos und meiner Wenigkeit! ;-) ).

Fehler im AROS Kernel werde ich nicht beheben, da ich dafür keine Zeit und auch keinen GCC installiert habe.
Mein GCC (3.3.0) für AROS x86 beschränkt sich darauf, Programme übersetzen zu können; dieser kann aber kein Betriebssystem erstellen - dazu müsste ich die Konfiguration nochmals überarbeiten und ein komplett neues GNU-C Toolchain bauen. Dazu fehlt mir aber schlichtweg die Muße.

Eine kleine, oberflächliche Dokumentation zu den verwendeten BCPL-Funktionen werde ich aber beifügen - diese ist aber eher für Nostalgiker wie mich gedacht denn fürs seriöse programmieren neuerer Betriebssysteme.

Grüße

--
Stupid mistakes are always made by others -
we only make unavoidable errors
 
jolo   Nutzer

23.06.2018, 09:22 Uhr

[ - Direktlink - ]
Thema: Global Vektor
Brett: Programmierung

Global Vektor - das AmigaDOS der ersten Stunden.

Ich habe mich mehr oder weniger mit dem in BCPL verfassten AmigaDOS beschäftigt und stelle mir gerade die Frage, ob es irgendwo halbwegs offizielle Bezeichner der Funktionsindexe und Variablen gibt, also die Positiven, im Bereich von 0 bis 133, evtl. auch die Bezeichner für die CLI-Struktur von 134 bis 149, obschon ich deren Bezeichnung als unwichtig erachte.

Hintergrund ist der, dass ich nur anhand der Funktionen bzw. der benutzen Variablen-Einträge Mutmaßungen für die Bezeichnung anstellen kann.

Ich glaube mich zu erinnern, dass die Indexe mit "g_" eingeleitet wurden, bin mir aber nicht mehr sicher, da ich auf keiner Entwickler-CD irgendwelche Beispiele, die diese verwenden, finde. Vielleicht narrt mich hier auch mein Gedächtnis.
Und bitte nicht auf AROS verweisen; dort ist die Tabelle (Vektor) massiv fehlerhaft, und wenn die Indexe fehlerhaft sind, gehe ich davon aus, dass es die Bezeichner erst recht sind.

Hintergrund warum ich mich eigentlich mit der Materie beschäftigt habe ist der, dass ich ein OS2+ CLI-Programm auf OS1.2 zurück portieren wollte, dabei aber eine Funktion wie ReadArgs() benötigte, diese wiederum im BCPL geschriebenen AmigaDOS existiert, die ich somit auch verwenden konnte, jedoch so neugierig wurde, dass ich das halbe in BCPL geschriebene AmigaDOS disassembliert habe und mittlerweile recht geübt im Schreiben von OS1.2 CLI Kommandos bin, inklusive Schreiben eines Startup-Codes der diesen globalen Vektor "privatisiert".

Aus sentimentalen Gründen möchte ich nun mein erlangtes Wissen auf Aminet "sichern", dabei stehen mir aber die Bezeichner im Weg.

Hat irgendjemand eine Quelle für mich?


Grüße

--
Stupid mistakes are always made by others -
we only make unavoidable errors
 
jolo   Nutzer

14.10.2017, 10:46 Uhr

[ - Direktlink - ]
Thema: Sound und Geschwindigkeitsprobleme bei WinUAE
Brett: AROS und Amiga-Emulatoren

@BlutAxt74:
> Ich hoffe mal das die neue CPU/Grakfikkarte es raus haut

Liegt mit Sicherheit nicht an der Grafikkarte. H.264 Kodierung/Dekodierung mit 30 FPS schaffen sogar 150 Euros Smartphones. Das bietet mittlerweile auch jede Low-Cost-Grafikkarte an, bei nicht nenneswerter CPU Last.

Wenn man die Specs meines Rechners in Betracht zieht, erkennt man, dass es sich hierbei um einen Nullachtfuffzehn-Laptop handelt. Da ich keinerlei Probleme mit Spielmitschnitte aufgezeichnet mit OBS Studio habe (selbst bei Vollbildschirm 3D-Ego-Shootern, dann allerdings nur in 1024x768), müsste Dein Laptop von der Rechenleistung her viel besser als der meinige dazu geeignet sein. Da bei Dir aber der Sound aus dem Ruder läuft bzw. WinUAE aus dem Tritt kommt, stimmt da etwas nicht.
Meine Vermutung ist, dass zu viel Müll im Hintergrund auf Deinem System ausgeführt wird.

Möglichkeit eins:
Nach einer Neuinstallation von Windows 10 werden mehr als 250 Prozesse gestartet sowie zwischen 20 und 60 Hintergrund-Apps. Hier kann man viel Rechenleistung gewinnen, wenn man sich nur auf das Nötigste beschränkt. Bei mir sind das 143 Prozesse und 0 Hintergrund-Apps.

Möglichkeit zwei.
Evtl. hast Du eine WinUAE-Konfiguration von einem bestehenden Rechner auf Deinem jetzigen übernommen. Das klappt aber nicht. WinUAE ist eine Zicke in dieser Beziehung. Also eine neue, auf diesem Rechner aufgesetzte Konfiguration benutzen.

Möglichkeit drei.
CPU und FPU sowie Display sind unter WinUAE nicht optimal konfiguriert.

Möglichkeit vier.
Es fehlt DirectX June 2010, dann kommt WinUAE bei der Darstellung und Audio-Ausgabe ins Schleudern, weil DirectDraw und DirectSound nicht richtig funktionieren.

Möglichkeit fünf.
Deine Festplatte ist zu langsam. In allen Windows-Versionen bremsen Festplattenzugriffe die gesamte Rechenleitung massiv ein.

Möglichkeit sechs.
Du benutzt WinUAE im Vollbildschirmmodus statt im Fenstermodus.

Möglichkeit sieben.
Du schneidest immer dann mit, wenn Windows irgendwelche Updates installiert.

Grüße
 
jolo   Nutzer

12.10.2017, 20:17 Uhr

[ - Direktlink - ]
Thema: Sound und Geschwindigkeitsprobleme bei WinUAE
Brett: AROS und Amiga-Emulatoren

@BlutAxt74:

WinUAE - es kann nur dann die vertikale Synchronisation ausgeschaltet oder auf Low-Latency umgeschaltet werden, wenn das betreffende Spiel nicht gerade die Display-Hardware zur Synchronisation benutzt. Meistens wird man aber nicht umhin kommen, die Einstellung auf "Legacy VSnc" umzustellen, so dass die Sounds korrekt abgespielt werden.
Leider kostet "Legacy VSnc" mehr Rechenzeit, OSD zeigt dann immer 100 bis 101 Prozent an.
Wie dem auch sei, für Spielmitschnitte, WinUAE im Fenstermodus betreiben, dabei eine eins-zu-eins Auflösung anstreben, z.B. 752x572 (PAL). Leider ist diese Auflösung etwas mickrig auf kleinen Laptop-Bildschirmen mit 1920x1080 Bildschirmpunkten, muss aber sein, sonst verzerrt sich das Video und es wirkt massiv unscharf (liegt an der Interpolation seitens WinUAE).
In OBS Studio gewünschte Video-Auflösung (1080p bei 10 kBits/s oder 720p bei 6 kBits/s bei 25 oder 30 Bildern pro Sekunde) mit Skalierung (Bilinear) wählen.
In OBS Studio Bildschirm des WinUAE-Fenster mittels der Ankerpunkte soweit vergrößern, dass nur der Inhalt des WinUAE-Fensters mitgeschnitten wird (Fummelei - geht aber).
Dann Aufnahme starten.

Mein Laptop (i5-5200, Windows 10, 64 Bit) mit nur zwei Kernen bei 2,2 GHz und Intel HD-Graphics 5500 zeichnet z.B. "Die Siedler" damit ohne Probleme auf, bei 20 prozentiger Last seitens WinUAE (32 Bit) und 10 Prozent seitens OBS Studio (64 Bit). Demnach braucht es keinen High-End-Rechner um so etwas aufzuzeichnen.
Ach ja, Telemetrie-Sendungen an Redmond und jeglicher anderer Scheiß der meine Privatsphäre tangiert inklusive Hintergrund-Apps gibt es auf meinem Laptop nicht (deaktiviert oder deinstalliert). Vielleicht liegt da Dein Problem; Windows 10 quatsch ja unentwegt mit seinem Zuhause.

Für Rechner mit nVidia Grafikkarten empfiehlt sich allerdings nicht OBS Studio sondern nVidias ShadowPlay, Voraussetzung ist dann allerdings ein Monitor, der mehr als FullHD darstellen kann, da sonst WinUAE im FullScreen-Modus die PAL/NTSC-Auflösung des Spiels interpoliert, was bescheiden schön aussieht.

Grüße
 
jolo   Nutzer

06.08.2016, 15:31 Uhr

[ - Direktlink - ]
Thema: AmigaBASIC-Objekte in anderes Format konvertieren
Brett: Amiga, AmigaOS 4

Ich kann nur spekulieren, aber da Shapes (der C16/Plus 4 lässt grüßen) auf dem Bob-Record aufbauen, denke ich, dass man keine Farben definieren muss - also die Farben nicht mit dem Objekt selber abgespeichert werden, es sei denn, man speichert das Objekt als Sprite, wobei dann allerdings nur vier Bytes auch nur drei Farben aufnehmen können (R4B4G4 - 12 Bit!) - ich denke, dass die transparente Farbe ausgespart wird. Ist aber nur eine Vermutung.

Hier die vordefinierten Farben des Kickstart v33/v34.
code:
Bitplane	Nummer	Farbe	Klartext
0		0	$05A	Blau 1
1		1	$FFF	Weiß 1
2		2	$002	Schwarz 1
		3	$F80	Orange
3		4	$00F	Blau 2
		5	$F0F	Pink
		6	$0FF	Türkis
		7	$FFF	Weiß 2
4		8	$620	Dunkelbraun
		9	$E50	Orange
		10	$9F1	Hellgrün
		11	$EB0	Ocker
		12	$55F	Hellblau
		13	$92F	Violett
		14	$0F8	Neongrün
		15	$CCC	Hellgrau 2
5		16	$000	Schwarz 2
		17	$E32	Rot
		18	$000	Schwarz 3
		19	$F96	Fleischfarben
		20	$444	Dunkelgrau 1
		21	$555	Dunkelgrau 2
		22	$666	Mittelgrau 1
		23	$777	Mittelgrau 2
		24	$888	Mittelgrau 3
		25	$999	Mittelgrau 4
		26	$AAA	Mittelgrau 5
		27	$BBB	Hellgrau 1
		28	$CCC	Hellgrau 2
		29	$DDD	Hellgrau 3
		30	$EEE	Hellgrau 4
		31	$FFF	Weiß 3


Das erste Hardware-Sprite (OCS-Sprites: maximal 16 Bits breit und 4 Farben, alle in Bitplane 5 angesiedelt) übernimmt immer die Farben der Bitplane 5, also standardmäßig transparent (Schwarz 2 wird nicht dargestellt), Rot, Schwarz 3 und Fleischfarben.
Öffnet man einen eigenen Bildschirm unter OS 1.2, 1.3, muss man auch zwingend die Farben (z.B. mit LoadRGB4()) verändern, ansonsten erhält man wieder diese vordefinierten Farben. In wie weit das Werkzeug zum Erstellen der Shapes das beim Abspeichern der Daten berücksichtig, kann ich nicht sagen. Um AmigaBasic und Basic im Generellen, habe ich immer einen großen Bogen gemacht.
Ich denke aber, dass man bei einer veränderten Farbpalette ohne den zugehörigen Basic-Quellcode nicht wirklich ein eins-zu-eins Abbild schaffen kann, da nur im Quelltext selber die Farben definiert sind - wozu soll man bei einem Bob (AmigaBasic nennt diese Shapes) denn eine Farbpalette mitgeben? Bobs sind nur binäre Datenwörter ohne Farbinformationen - das Remappen muss man heutzutage (True/Hicolour/256 Farbpalette) schon selber vornehmen. Aber wie gesagt, ohne den AmigaBasic-Quelltext, der die Farben definiert, wird es schwer.

Thomas, vielleicht helfen Dir die oben vordefinierten Farben ein bisschen weiter.
 
jolo   Nutzer

21.03.2015, 20:15 Uhr

[ - Direktlink - ]
Thema: Assembler/Includes: "unknown mnemonic <funcdef>"
Brett: Programmierung

Zu jedem kommerziellen Assembler damaliger Zeit wurden die passenden, sprich Assembler spezifischen LVO-Dateien ("nnn/nnn_lib.i") mitgeliefert, und die Datei "funcdef.i" geflissentlich ignoriert (anbei, diese Datei ist sowieso Assembler spezifisch und eigentlich nur für "exec/exec_lib.i" erdacht). Liegt darin begründet, dass LVOs nicht zwingend aneinanderhängend in der passsenden "FD"-Datei (also der Beschreibungsdatei zu einer Shared-Bibliothek) angegeben werden müssen, sondern ein Schlüsselwort Verwendung finden kann, um einen privaten Library-Vector-Offset zu deklarieren, der keinen gültigen Namen hat. Zudem kann man in den neueren (1991?) "SFD"-Dateien auch Einträge komplett übergehen, die damit dann gänzlich ohne Bezeichner sind.
Da das Makro FUNCDEF aber zwingend reguläre Bezeichner braucht, jedoch private Bezeichner ungültig und unschön sind, ist das FUNCDEF-Makro nicht wirklich passend. Zudem kostet das FUNCDEF-Makro Zeit, um die entsprechenden Offsets zu berechnen, so dass man sich auch noch aus Geschwindigkeitsgründen dafür entschieden hat, direkt die LVOs anzugeben ohne den Umweg über das FUNCDEF-Makro zu nehmen.
Zudem waren die von Commodore Amiga publizierten SDKs nicht für alle verfügbaren Assembler passend und mussten dementsprechend sowieso nachgebessert werden, warum also nicht gleich die LVOs direkt hinein schreiben?

Zusammenfassung:
"funcdef.i" ist Assembler spezifisch.
"funcdef.i" ist nur erdacht für "exec/exec_lib.i", die anderen LVOs sollten nach Willen von Commodore Amiga beim Linken der "amiga.lib" entnommen werden.
"funcdef.i" ist unschön, weil private Bezeichner Verwendung finden.
"funcdef.i" ist zeitaufwändig, weil Berechnungen durchgeführt werden müssen.

Gegenmaßnahme:
Ersatzlos streichen und aus der Devpac-Entwicklungsumgebung die "nnn/nnn_lib.i"-Dateien klauen. :-)
 
jolo   Nutzer

20.03.2015, 18:51 Uhr

[ - Direktlink - ]
Thema: Assembler/Includes: "unknown mnemonic <funcdef>"
Brett: Programmierung

Ist illegal. Wird trotzdem von manchen Assemblern auf Source-Code-Basis akzeptiert, jedoch beim Übersetzen in ein "NOP" gewandelt.
 
jolo   Nutzer

31.01.2015, 16:42 Uhr

[ - Direktlink - ]
Thema: WinUAE Soundproblem
Brett: AROS und Amiga-Emulatoren

Unter Windows 8.1 und WinUAE 3.0.00 hatte ich am Anfang auch diverse Probleme und wollte wieder auf WinUAE 2.8.10 zurückwechseln, jedoch spiele ich nicht sondern benutze WinUAE zum Programmieren.

Workbench: Brauchte eine gefühlte Ewigkeit bis sie erschien. War vorher immer ruck-zuck geladen.
Tastatur: Tasten verwandten die englischen RAW-Key-Codes für Sondertasten.
Sound: Nach dreißig bis vierzig Sekunden lief der Sound aus dem Ruder. Zudem gab es Zisch- und Kratzgeräusche.
Programme stürzten ab, die vorher immer einwandfrei liefen.

Hatte nach drei Abenden mit herumexperimentieren die Nase voll und dann eine komplett neue Konfigurationsdatei für WinUAE angelegt, also keine vorhandene abgeändert.
Workbench war dann wieder ruck-zuck geladen, Auflösung passte, Zurückswitchen zum Desktop ging wieder innerhalb von Sekundenbruchteilen, Sound lief ordnungsgemäß und stabil.
Nur passte die Tastaturbelegung noch immer nicht zu meiner deutschen PC-Tastatur; beim Drücken von 'ALT-GR + ß' wurde das Doppelkreuz ausgegeben anstelle vom Backslash '\'.
Also originale "Default (PC-KB)" in Config #1 kopiert, die falschen Zuweisungen rausgenommen und auf ihre Default-Werte gesetzt und unter AmigaOS3 eine neue deutsche "Keymap" erstellt, die entsprechend der Symbole auf der Tastatur agiert.

Ich bin jetzt zufrieden.

Anbei, WinUAE war schon immer eine Zicke bezüglich der Tastatur-Layouts... Und, das Experimentieren mit dem Sound-TAB kannst Du Dir sparen, habe ich auch versucht, daran liegt es nicht...
Wo der Fehler liegt, kann ich aber allerdings auch nicht sagen...

 
jolo   Nutzer

12.08.2014, 17:51 Uhr

[ - Direktlink - ]
Thema: Wo sind die Pens hin?
Brett: Programmierung

Dass hier ein Begriff gebraucht wird ("Schwachsinn"), den man heute selbst in der Psychiatrie, dort wo er nämlich herstammt, nicht mehr verwendet, solltet auch ihr so klug sein, diesen nicht mehr zu verwenden.

Eine unüberlegte/fehlerhafte/unsinnige Handlung/Aussage mit Schwachsinn gleichzusetzen, entbehrt jeder Grundlage (um es gelinde auszudrücken).

Zudem, den Vorschlag 0x29024 als Monitor-ID herzunehmen, ist falsch (bezugnehmend auf die 640x512 Auflösung), da dies einer Auflösung von 1280x512 entsprechen würde.

Zitat:
die einem gestandenen Amiga-Programmierer

Hätte ein "gestandener Amiga Programmierer" sich die Frage nicht selber beantworten können?
--
Stupid mistakes are always made by others -
we only make unavoidable errors
 
jolo   Nutzer

13.10.2013, 17:35 Uhr

[ - Direktlink - ]
Thema: CRYENGINE Free SDK ist das was für unseren Amiga Plattform?
Brett: Amiga, AmigaOS 4

@xXSoul-Reaver-2006Xx:

Wenn Du Microsoft dazu bewegen kannst, DirectX und speziell Direct3D auf die jeweilige Plattform zu portieren...

Jetzt mal im Ernst, nein, ist nutzlos.
 
jolo   Nutzer

07.05.2013, 20:46 Uhr

[ - Direktlink - ]
Thema: AROS, doch noch so instabil ?!
Brett: AROS und Amiga-Emulatoren

@Georg

Habe neues AROS-Kernel installiert und Tests durchgeführt. Der Bug bezüglich scheinbar gelocktem Layer ist nicht mehr vorhanden, so dass ich jetzt wieder ClipBlit() verwende.

Grüße
--
Stupid mistakes are always made by others -
we only make unavoidable errors
 
jolo   Nutzer

05.05.2013, 11:12 Uhr

[ - Direktlink - ]
Thema: AROS, doch noch so instabil ?!
Brett: AROS und Amiga-Emulatoren

Zitat:
also nach überlegung verstehe ich glaube ich das problem und sehe eher schwarz für baldige vbcc umsetzung.

Dito.


Zitat:
ich habe auch den eindruck dass vbcc mag, ähnlich wie gcc 2.9.x etwas überschätzt sein, ja es ist bestimmt mehr mit augenmerk auf 68k zugeschnitten, aber wie kann man arbeit von zwei leuten mit ganzen teams vergleichen.

Erstens, ich überschätze 'vbcc' definitiv nicht, ich weiß wo dieser seine Schwachstellen hat, jedoch ist dieser dermaßen portabel, dass man selbst in der Lage ist unter 'Windows' (egal welche Version) Programme für AmigaOS3, MorphOS und AmigaOS4 zu erstellen, ohne irgendwelche Laufzeitumgebungen zu erstellen! Ich hatte schon massive Schwierigkeiten mir einen 'gcc' für AmigaOS3 zusammen zu stellen, welcher AROS-x86 Code generiert... Ergo, 'vbcc' ist portabel, 'gcc' nur schwerlich und ohne Kenntnisse gar nicht zu portieren, zudem verlangt 'gcc' nach einer LINUX-Umgebung, 'vbcc' aber nicht!
Zweitens, 'vbcc' Augenmerk liegt ganz bestimmt nicht auf CISC-Prozessoren, sondern auf RISC, auch wenn dieser klaglos 'm68k' oder auch 'x86' Code generiert, jedoch hier dann und wann Optimierungen nicht wahrgenommen werden. Nach wie vor produziert SAS/C besseren 'm68k' Code - dieser ist aber auch nicht optimal auf 'm68k' zugeschnitten (der Green Hills Software C-Compiler ist das Maß der Dinge für 'm68k' (kommerziell und nicht für AmigaOS erhältlich)) und 'gcc' besseren x86(/64) Code. CISC-Instruktionen sind für einen Compiler suboptimal, RISC-Instruktionen kommen einem Compiler jedoch sehr entgegen.
Drittens, nur einer entwickelt den 'vbcc' Compiler-Kern, und das ist Dr. Barthelmann, und da kann man nur staunen, dass einer alleine so etwas bewerkstelligt und noch dazu seinen Compiler Code generieren lässt (jedoch mit massiver Hilfe von Frank Wille), der Vergleiche mit einem 'gcc'-Compiler für 'm68k' und 'PPC' nicht scheuen muss, obschon hinter 'gcc' eine Heerschar von Programmierern steht.
Die Nachteile von 'vbcc' sind klar auf der Präprozessorseite zu suchen (der 'gcc'-Compiler erlaubt hier Dinge, die 'vbcc' nicht beherrscht) und dass 'vbcc' ausschließlich ein C-Compiler ist, während man innerhalb der GNU-Toolchain auch auf andere Programmiersprachen ausweichen kann (z.B. C++).
Viertens, 'gcc' ist die erste Wahl wenn man denn Programme von *NIX-artigen Betriebssystemen portieren will oder für x86(/64) entwickelt. Dies mache ich aber nicht bzw. nur sporadisch. Für mich steht das schnelle portieren eines Programmes innerhalb der verschiedenen Amiga-ähnlichen Betriebssysteme an erster Stelle, und da ist halt 'vbcc' die wesentlich bessere Wahl.
Zudem geht es mir nicht darum, das AROS-Btriebssystem mittels dem 'vbcc'-Compiler selber zu erstellen, sondern ausschließlich um *meine* Programme.
Aber, das ist alles am Thema vorbei; hier geht es um eventuell vorhandene AROS-Bugs und nicht um 'gcc' oder 'vbcc'.


Zitat:
Georg:
Welche Header müssen gefixt werden und welche Art von Fixes? Viele Header sind ja auto-generiert, und da müßte man ja nur die Skripte fixen, die diese erzeugen.


Wäre es nicht besser, Frank Wille direkt zu kontaktieren, anstatt meine Fixes (Hacks) als Ausgangsbasis zu benutzen? Ich habe versucht, nur ein einziges Programm mittels 'vbcci386' zu übersetzen, und ich bin kläglich gescheitert.


Zitat:
Georg:
Zitat:Original von jolo:

Bei mir ist es immer ein RGB24-PixelArray (malloc()), um welches ich eine Bitmap- und Rastport-Struktur herum baue.

Zitat:
Wie machst du das genau?

Normalerweise würde man ja AllocBitMap() mit flags = BMF_SPECIALFMT | SHIFT_PIXFMT(PIXFMT_RGB24) verwenden.

Oder - wenn man nicht mit graphics/cgfx Funktionen in das PixelArray rendern will - überhaupt keine BitMap sondern WritePixelArray(RECTFMT_RGB).



So wie Du es oben beschrieben hast:

code:
ged->bm = AllocBitMap( ((gad->Width + 15) & -16), gad->Height, 24,
                       BMF_MINPLANES | BMF_SPECIALFMT | SHIFT_PIXFMT(PIXFMT_RGB24),
                       NULL);


und bei Bedarf dann:

code:
InitRastPort( &ged->rp);
ged->rp.BitMap = ged->bm;

/* Render image to the previously created (OM_NEW) BitMap */
WritePixelArray( ged->sbutton->data, 0, 0, ged->sbutton->modulo,
                 &ged->rp, 0, 0,
                 ged->sbutton->sizeX, ged->sbutton->sizeY, RECTFMT_RGB);


wobei "ged" auf diese Struktur zeigt:

code:
struct RGBButton
{
	ULONG type;
	struct DrawInfo *drawInfo;	/* Perhaps for future versions I need it */
	struct canvas *ubutton;		/* Unselected and adapted button image */
	struct canvas *sbutton;		/* Selected and adapted button image */
	LONG  min, max, curr;		/* Progress gadget values */
	struct BitMap *bm;		/* 24-bits (RGB) */
	struct RastPort rp;		/* Private RastPort pointing to the above BitMap */
	LONG oldX, newX;		/* Only really required on the part of OS3 */
	ULONG flags;			/* See below */
};


und "canvas" das Basisabbild enthält:

code:
struct canvas	/* Always for the RGB format (each 8 bits per gun) */
{
	uint32	sizeX;		/* Width in pixel of entire canvas */
	uint32	sizeY;		/* Height in pixel of entire canvas */
	uint32	modulo;		/* Modulo (bytes per line of pixel) of canvas */
	uint32	leadin;		/* Normally 1 - so the left/top is not at 0/0 but at
				   1/1 in order to be able to apply bilinear patch */

	/* Bounding box taken by the rendered image */
	uint32	left;		/* X-offset of image in canvas */
	uint32	top;		/* Y-offset of image in canvas */
	uint32	right;		/* The width of the image */
	uint32	bottom;		/* The height of the image */

	float	scaleX;		/* The used scale factors */
	float	scaleY;

	uint32	bgRGBA;		/* RGBA background colour */
	uint8	*data;		/* Pointer to data */
};


Somit enthält "Bitmap" (ged->BitMap) nur eine Kopie der "canvas", auch wenn es noch nachträglich um grafische Elemente erweitert wird. Sollte daher unter jedem AmigaOS3 Quellcode-kompatiblen Betriebssystem funktionieren.
 
jolo   Nutzer

03.05.2013, 20:28 Uhr

[ - Direktlink - ]
Thema: AROS, doch noch so instabil ?!
Brett: AROS und Amiga-Emulatoren

Zitat:
wawa:
kann man aros mit vbcc erwartungsgemäss wirklich bauen?


Im Moment, nein. Ich verwende selber für AROS x86 den 'gcc' Compiler, weiß aber, dass Frank Wille einen 'vbcc'-AROS x86 Compiler in petto hat, welcher aber noch experimentell ist. Ich habe diesen zwar auch installiert, bei mir harmoniert dieser aber nicht mit dem AROS-SDK. Ich habe zwar etliche Header-Dateien aus dem AROS-SDK für den 'vbcc'-Compiler gefixt (auch auf Assembler-Ebene), aber es ist ein unendliches Unterfangen, so dass ich irgendwann das Handtuch geworfen habe.


Zitat:
Georg:
Hängt das jedesmal wenn ClipBlit oder BltBitMapRastPort() in GM_RENDER benutzt wird, oder nur in best. Situationen (z. B. Fenster Vergrößern oder Verschieben wenn es ein SIMPLE REFRESH Fenster ist)? btw: innerhalb eines BeginRefresh()/EndRefresh() keine Funktionen benutzen die direkt/indirekt Gadget Rendern auslösen können!


Schon beim ersten Aufstarten des betreffenden Programmes hängt Intuition. Und ja, es ist ein SIMPLE_REFRESH Fenster. Und nein, innerhalb von BeginRefresh()/EndRefresh() wird rein gar nichts am Display geändert. Siehe Code:

code:
if (iclass == IDCMP_SIZEVERIFY)
{
    if (GadgetsAccessible)
    {
        /* Unlink the gadgets from the window */
        UncoupleGadgets( win, glist, &gmask);
        GadgetsAccessible = 0;
    }

    if (msg)
        ReplyMsg( (struct Message *) msg);

    msg = NULL;     /* Wait till an event occurs */
    while ( !msg)
    {
        WaitPort( win->UserPort);
        msg = (struct IntuiMessage *) GetMsg( win->UserPort);
    }
    iclass = msg->Class;
    icode = msg->Code;
    iqualifier = msg->Qualifier;
    iaddr = (struct Gadget *) msg->IAddress;
    cSeconds = msg->Seconds;
    cMicros = msg->Micros;
}

if (msg)
    ReplyMsg( (struct Message *) msg);
else
    break;

switch (iclass)
{
    case IDCMP_CLOSEWINDOW:
        terminate = TRUE;
        break;

    ....
    ....
    ....


    case IDCMP_REFRESHWINDOW:
        /* Normally, only the damaged regions of a window
           (actually, layer) will be accessible by the gfx-
           primitives, like Text(), RectFill() and so on
           and not those which weren't damaged. This speeds up
           the drawing operations a lot, unfortunately, we
           going to spend much more time laying out and
           rotating an image so this Intuition feature
           (actually, Graphics/Layer) doesn't bother us too
           much! */
        BeginRefresh( win);
        EndRefresh( win, TRUE);
        /* Entire window is now again accessible, i.e.
           the damage regions detected by Layers library
           were thrown away and we can render in any pixel in
           the window. */

        RefreshFrames( win, &layer);
        width = layer.MaxX - layer.MinX;
        height = layer.MaxY - layer.MinY;

        FillPixelArray( win->RPort,
                        layer.MinX, layer.MinY,
                        width, height,
                        (BG_COLOUR >> 8 ) & 0x00FFFFFF);

        if (GListPtr)
        {
            if (GadgetsAccessible)
            {
                RefreshGList( GListPtr, win, NULL, -1);
            }
            else    /* IDCMP_SIZEVERIFY caused us to remove GList */
            {
                AddGList( win, GListPtr, -1, -1, NULL);
                GadgetsAccessible = 1;
                AttachGadgets( win, RgbProgressBar, glist, &gmask);
                RefreshGList( GListPtr, win, NULL, -1);
            }
        }

        /* Re-render the image */
        if (scv)
        {
            if (adaptMode == SCALE_TOFIT)
            {
                if (angle != .0)
                    cv = canvas_rotate( scv, angle, width, height, patch);
                else
                    cv = canvas_scale_rigid( scv, width, height, patch);

                if (cv)
                {
                    if (cv->sizeX > width)
                        maxX = width;
                    else
                        maxX = cv->sizeX;

                    if (cv->sizeY > height)
                        maxY = height;
                    else
                        maxY = cv->sizeY;

                    /* I know, I know. A lot of people seem to believe that
                       multiple IDCMP_REFRESHWINDOW events should be collected
                       and processed as one or that multiple refresh requests
                       should be skipped - this code proves them all wrong.
                       If the damage regions were restored properly, each
                       IDCMP_REFRESHWINDOW is essential and indicates another
                       change to the display - just uncomment the following
                       line and see what happens. When for some reason a
                       message will be removed by SkipMultiRefreshMsgs() a
                       display corruption will occur.
                    */
/*                              SkipMultiRefreshMsgs( win->UserPort, win); */

                    WritePixelArray( cv->data, 0, 0, cv->modulo,
                                     win->RPort, layer.MinX, layer.MinY,
                                     maxX, maxY, RECTFMT_RGB);

                    DisplayChanges( win, scv, cv, angle, glist, gmask);
                    UpdateZoomMenu( win, cv->scaleX);

                    canvas_free( cv);
                }
            }
            else
            {
                if (adaptMode == NOSCALE_TOFIT)
                {
                    DisplayFullSized( win, scv, angle, scalef,
                                      patch, FALSE, FALSE,
                                      &layer,
                                      deltaX, deltaY,
                                      glist, gmask);
                }
            }
        }
        break;

    case IDCMP_NEWSIZE:
        /* Never ever throw away damage regions in IDCMP_NEWSIZE -
           i.e. using Begin/EndRefresh - then
           IDCMP_REFRESHWINDOW would not be called at all! */
        #if defined(__AROS__)
        if (GadgetsAccessible)
        {
            /* Unlink the gadgets from the window */
            UncoupleGadgets( win, glist, &gmask);
            GadgetsAccessible = 0;
        }
        #endif
        break;



Zitat:
Georg:
Also ich hab' das hier (ABI V0) getestet und sowohl BltBitMapRastPort() als auch ClipBlit() funktionieren in GM_RENDER.


Ich werde eigene Tests am Wochenende/Anfang der nächsten Woche durchführen, um zu erfahren, ob dieser Bug zwischenzeitlich verschwunden ist.
Meine AROS x86 Installation ist nicht auf dem neusten Stand, daher muss ich diese erst einmal erneuern.

Zitat:
code:
tempbm = AllocBitMap(w,h,0,0,msg->gpr_RPort->BitMap);



Bei mir ist es immer ein RGB24-PixelArray (malloc()), um welches ich eine Bitmap- und Rastport-Struktur herum baue.


Zitat:
wawa:
warum testest du mit v0? es besteht glaube ich keine gerantie dass es auch unter v1 richtig arbeitet. aros68k ist v1!


Der Bug trat unter ABI v0 auf; der Funktionscode (Funktionsweise) sollte jedoch identisch in beiden Varianten sein, auch wenn die CPUs (Binärcode) und die Art der Parameterübergabe differieren.
 
jolo   Nutzer

29.04.2013, 20:15 Uhr

[ - Direktlink - ]
Thema: AROS, doch noch so instabil ?!
Brett: AROS und Amiga-Emulatoren

Zitat:
wawa:
ich glaube jason hat versucht soweit wie moeglich in richtung vbcc vorzustossen, hat die arbeit aber abgebrochen als es zu kompliziert wurde und andere aufgaben dringender waeren. das alles kein boeser wille, es fehlt halt an mannschaft.


Das SDK selber wird nicht ohne weiteres unter 'vbcc' verwendbar sein, da es maßgeschneidert für 'gcc' ist. Wäre man in 2005(?) auf Frank Willes Anregungen eingegangen und hätte das SDK so erweitert, dass die Compiler-spezifischen Sachen in Unterverzeichnisse gewandert wären, hätte sich das für mich leidige Thema "AROS is programmable only by means of the gcc-compiler!" erübrigt.


Zitat:
wawa:
koenntest du nicht aros team dabei unterstuetzen die idcmp und rastport angelegenheit auszubuegeln?


Bug-Report bezüglich des Render-Bugs wurde von mir 2011 eingestellt.
Das IDCMP-Handling können die AROS-Entwickler nach Gutdünken handhaben; es ist kein Bug sondern eine Inkompatibilität zu OS3, MorphOS, AmigaOS4.


Zitat:
Georg:
Was meinst du genau? Rastports können nicht gelockt werden. Wenn RastPort->Layer gemeint ist: wie sieht der Code aus, der das System einfriert?


Hier ist der Code, aber ich glaube kaum, dass Du mit diesem was anfangen kannst, daher beschreibe ich unten das Problem.


code:
case GM_RENDER:
{
    struct GadgetInfo *ginfo = ((struct gpRender *) msg)->gpr_GInfo;
    struct RastPort *rp = ((struct gpRender *) msg)->gpr_RPort;
    struct Gadget *gad = (struct Gadget *) o;
    #if defined(__AROS__)
    ULONG x, y;
    #endif

    #ifdef DEBUG
    kprintf( "GM_Render called!\n");
    #endif

    ged = INST_DATA( cl, o);
    if (rp && ginfo)
    {
        if ( (gad->Flags & GFLG_SELECTED) && !(gad->Flags & GFLG_GADGHNONE))
            DrawSelected( (struct Gadget *) o, ged, ginfo, rp);
        else
            DrawUnselected( (struct Gadget *) o, ged, ginfo, rp);

        /* Blast the entire pre-drawn image into the display if it
           is of type PROGRESS BAR */
        if (ged->type == RGB24TYPE_PROGRESS)
        {
    #if !defined(__MORPHOS__) && !defined(__AROS__) && !defined(__amigaos4__)

            /* OS3 stuff is more complicated than the others, because we
               can't draw directly texts into a 24-bit offscreen
               PixelArray */
            if ( ged->oldX > ged->newX || (ged->newX == 0 && ged->oldX == 0) ||
                 (ged->flags & FORCE_REFRESH) )
            {
                ged->flags &= ~FORCE_REFRESH;

                /* Entire gadget to be rendered */
                ClipBlit( &ged->rp, 0, 0,
                          rp,
                          gad->LeftEdge, gad->TopEdge,
                          gad->Width, gad->Height,
                          0xC0);    /* Cookie cut */
                ged->oldX = 0;
                ged->newX = 0;
            }
            else
            {
                /* Just render what is affected */
                ClipBlit( &ged->rp, ged->oldX, 0,
                          rp,
                          gad->LeftEdge + ged->oldX, gad->TopEdge,
                          ged->newX - ged->oldX, gad->Height,
                          0xC0);    /* Cookie cut */
                ged->oldX = ged->newX;
            }

            if (ginfo && ((struct Gadget *) o)->GadgetText)
            {
                if (ged->oldX == 0 || (ged->flags & FORMAT_USED) )
                    RenderGadText( (struct Gadget *) o, ged, ginfo, rp);
            }
    #else
            /* MorphOS, AROS, AmigaOS4 */
            ged->flags &= ~FORCE_REFRESH;

            /* Render the text into the 24-bit PixelArray */
            if (ginfo && ((struct Gadget *) o)->GadgetText)
                RenderGadText( (struct Gadget *) o, ged, ginfo, rp);

            /* ...and bring it to the display */
            #if !defined(__AROS__)
            ClipBlit( &ged->rp, 0, 0,
                      rp,
                      gad->LeftEdge, gad->TopEdge,
                      gad->Width, gad->Height,
                      0xC0);    /* Cookie cut */
            #else   /* AROS has got serious problems with the destination
                       RastPort, Layer respectively */
            x = ginfo->gi_Window->LeftEdge;
            y = ginfo->gi_Window->TopEdge;
            BltBitMap( ged->bm, 0, 0,
                      rp->BitMap,
                      gad->LeftEdge + x, gad->TopEdge + y,
                      gad->Width, gad->Height,
                      0xC0,         /* Cookie cut */
                      ~0,           /* All BitPlanes */
                      NULL);        /* No temporary allocated raster */
            /* Using either ClipBlit, BltBitMapRastPort and alike functions
               under AROS result in a complete lockdown of Intuition! */
            #endif

            ged->oldX = 0;
            ged->newX = 0;
    #endif
        }
        else    /* Normal button, render text directly to the display */
        {
            if (ginfo && ((struct Gadget *) o)->GadgetText)
                RenderGadText( (struct Gadget *) o, ged, ginfo, rp);
        }
    }
    else
    {
        #ifdef DEBUG
        kprintf( "GM_RENDER: No Rastport!\n");
        #endif
    }

    retval = ANYTHING;
}
break;



Bei der Verwendung aus einer eigenen BOOPSI-Klasse heraus, die mittels ClipBlit() oder BltBitMapRastPort() eine Off-Screen-Bitmap (RGB24) ins entsprechende Fenster zeichnen will (GM_RENDER), hängt sich das System unter AROS auf. Unter AmigaOS3, MorphOS und AmigaOS4 hingegen nicht.
Abhilfe schafft hier nur das Umgehen der Layer-basierenden Zeichenmethoden, also das direkte Zeichnen in die On-Screen-Bitmap mittels BltBitMap(), unter Verwendung von "rp->BitMap" und manuelles addieren der Offsets (entnommen von gi_Window). Dabei kann es aber passieren, dass beim verkleinern des betreffenden Fensters über die Fenstergrenze hinaus gezeichnet wird… Unschön, aber derzeit nicht anders möglich...

Ist so auch als Bug-Report von mir gepostet worden.
 
jolo   Nutzer

28.04.2013, 11:20 Uhr

[ - Direktlink - ]
Thema: AROS, doch noch so instabil ?!
Brett: AROS und Amiga-Emulatoren

Zitat:
getestet mit wanderer, scalos und magellan, ist also irgendwo "lower level". layers, intuition, graphics lib?

Wird wohl am IDCMP-Handling seitens AROS liegen, welches nicht konform zum AmigaOS arbeitet, speziell beim vergrößern/verkleinern von Fenstern. Zudem gibt es einen massiven Bug beim Locken von RastPorts bei Verwendung von eigenen BOOPSI-Klassen, der das gesamte System einfriert.


Zitat:
* zlib Wrapper Code für Amiga Shared library schreiben => 5 h

Sorry, aber das ist Quatsch. Dafür gibt es mittlerweile Werkzeuge, die einem die meiste Arbeit abnehmen. Die AROS-Devs benutzen dafür unter UNIX ein Skript; ich dafür ein selbstgestricktes Plattform unabhängiges Programm welches AmigaOS3, AROS (i386), MorphOS und AmigaOS4 abdeckt.
Sofern der Quellcode von Hause aus thread-safe ist, dauert so etwas maximal 10 Minuten. Bei einer PNG oder einer JPEG-Lib natürlich wesentlich länger, da man die POSIX Speicher und IO-Funktionen unter Umständen mittels den OS-Funktionen nachbilden muss - jedoch hängt dies auch stark vom verwendeten Compiler ab und den verwendeten Link-Libs. Ich verwende dazu 'vbcc', und da kann man halt nicht auf 'gcc-only' Link-Libs zurückgreifen. Erschwerend kommt hinzu, dass die AROS-Developer ausschließlich auf 'gcc' fixiert sind und alle anderen Compiler außen vor lassen.
Aber zurück; eine Shared-Lib heutzutage zu erstellen, ist lange nicht mehr so kompliziert wie noch vor ein paar Jahren.

 
jolo   Nutzer

07.01.2013, 19:04 Uhr

[ - Direktlink - ]
Thema: AOS4 GCC und makefile-Probleme
Brett: Programmierung

@Thore

Hast recht, ".cpp.o:" ist die Kurzschreibweise für "%.o: %.cpp", Bisher habe ich dies aber nur unter "nmake" (Windows Visual Studio Tool-Chain) verwendet und nennt sich dort "Suffix-Regel". Dass GNU-Make es auch unterstützt, wusste ich bis dato nicht, da ich selber immer die Standard-Notation unter GNU-Make verwende. Manchmal sollte ich doch mal einen Blick in die Anleitung werfen...

'nmake' (Windows) Beispiel:

code:
# Compile the sources to objects within the root of the sources tree,
# and then move them into the objects directory. Afterwards delete the
# objects in the root of the sources tree.
{$(WRKDIR)}.cpp{$(OBJDIR)}.obj:
	$(CC) $(CCFLAGS) $(DEFINES) /c $<
	copy $(*F).obj $(*R).obj
	erase $(*F).obj


Wie auch immer, es mutet sich komisch für mich an, da bei dieser Suffix-Regel erst die Voraussetzung und dann das Ziel spezifiziert wird. Aber egal; wenn es denn funktioniert kann man es als solches auch benutzen.


@Reth

Vielleicht unterstützt Deine Version von GNU-Make auch das nachstehende, damit kannst Du bei Deinem 'make-file' einiges an Tipparbeit einsparen:

code:
# Alle Quelldateien
SRCS = main.cpp nnn.cpp xxx.cpp yyy.cpp

# Objektdateien anhand der Quelldateien :) 
OBJS = $(SRCS:.cpp=.o)



Zitat:
Weiss jmd., wie ich make aus der Amiga-Shell auch dazu bekomme, sdl-config nutzen zu können? SDL ist normal installiert.

Nee, leider nicht. Habe weder die SDL Header-Dateien noch SDL selber hier installiert.



Mal ein kurzes Beispiel für Objektdateien die *nicht* innerhalb des Quellcodeverzeichnisses erstellt werden; da ich selten in C++ programmiere, hier das Beispiel für den 'vbcc'-Compiler und anhand imaginärer C-Quellcodes:

code:
# Spezielles POSIX-Verzeichnis für vbcc m68k...
POSIXINC = vbcc:targets/m68k-amigaos/posix

# Wohin kommen die Objektdateien?
OBJDIR = objects

# Objektdateien
OBJS =  $(OBJDIR)/main.o  \
	$(OBJDIR)/addon.o

# Zielprogramm
TARGET = mytestprogram

# Compiler
CC = vc +aos68k -DAMIGA

# Andere Werkzeuge
MKDIR	= MakeDir
RM	= Delete
RMOPTS	= ALL QUIET

# Merkmale fürs Kompilieren
CFLAGS  = -I$(POSIXINC) -I"" -c99 -cpu=68020 -fpu=68881 -O1 -c

# Merkmale fürs Linken
LDFLAGS = -lvc -lposix -lamiga -lm881

# Erste Regel...
all: $(TARGET)

# Linken...
$(TARGET): $(OBJDIR) $(OBJS)
	$(CC) -o $(TARGET) $(OBJS) $(LDFLAGS)

# Unterverzeichnis erstellen, falls nicht vorhanden...
$(OBJDIR):
	$(MKDIR) $(OBJDIR)

# Alles zurücksetzen...
clean: FORCE
	@$(RM) $(RMOPTS) $(OBJDIR)
	@$(RM) $(RMOPTS) $(TARGET)
FORCE:

# Abhängigkeiten schaffen und kompilieren... (*1)
$(OBJDIR)/main.o: main.c dependencies.h
	$(CC) $(CFLAGS) $< -o $@
$(OBJDIR)/addon.o: addon.c adddon.h rules.h
	$(CC) $(CFLAGS) $< -o $@


(*1) Der Nachteil hier ist dass, falls ein anderes Verzeichnis für die Objektdateien gewählt wurde, man explizit den Compiler-Aufruf angeben muss, inklusive Ausgabedatei (-o $@)! Wenn Quell- und Objektdateien sich im gleichen Verzeichnis befinden, kann dieses "Rezept" entfallen!


Grüße

 
jolo   Nutzer

05.01.2013, 12:15 Uhr

[ - Direktlink - ]
Thema: AOS4 GCC und makefile-Probleme
Brett: Programmierung

Zitat:
Original von Reth:
.cpp.o:
$(CC) $(CCFLAGS) -O2 $(INC) -c $<


Das kann nicht funktionieren; korrekt müsste es so lauten:

code:
%.o: %.cpp


Bei manchen 'Make'-Applikationen darf man den '.' vor der Dateiendung weglassen:

code:
%o: %cpp




Merke, jede Regel wird so formuliert:

code:
Ziel: Voraussetzung [Voraussetzung] [Voraussetzung] [...]
	[Rezeptur]
	[...]
	[...]


Dabei können getrennt durch Freizeichen oder Tabs mehrere Voraussetzungen angegeben werden.
Auch kann man die Rezeptur(en) weglassen, und die voreingestellte Handhabung dieser Regel durch 'make' ausführen lassen.

Z.B. würde ich die Regel für "%.o: %.cpp" gar nicht spezifizieren, sondern am Ende des Quelltextes für 'make' die Regeln aufstellen, und zwar für jeden C++ Quellcode:

# dependencies
name1.o: name1.cpp name1.h name2.h name3.h
name2.o: name2.cpp name2.h name4.h name7.h
name3.o: name3.cpp name3.h name7.h name8.h
usw.

Anbei, Deine Dateien, die in HFILES gelistet sind, spielen nur beim Übersetzen der '.cpp'-Dateien eine Rolle (also deren Voraussetzung), nicht jedoch für das Erstellen des eigentlichen Ziels ("APP=gigalomania")! Ergo, gehören sie nicht in die Regel für "$(APP)", da sie hier nichts bewerkstelligen!



Zitat:
Original von Reth:
Ups, habe gerade gesehen, dass ich ja die Header und Sourcen in eigene Unterverzeichnisse gesteckt habe und diese hier im Makefile noch fehlen.

Weiss zufällig jmd., wie ich bei solchen allgemeinen Pattern in makefiles noch Verzeichnisse für die Source-, Header- und Objektdateien angeben kann?



[code]
Aus,
%.o: %.cpp

das machen:


OBJDIR = deinVerzeichnis/
SRCDIR = deinVerzeichnis/

und dann:

$(OBJDIR)%.o: $(SRCDIR)%.cpp
[code]

Obacht, falls Du GNU-Make verwendest musst Du evtl. die UNIX-Schreibweise für Verzeichnisebenen anwenden, z.B. "../" anstelle von "/" oder "." anstelle von "".

Grüße
 
jolo   Nutzer

01.01.2013, 23:35 Uhr

[ - Direktlink - ]
Thema: Gibt es ein Standard-#define für Amiga-Systeme?
Brett: Programmierung

Nee, leider nicht, obschon unter GNU-C bei meiner Installation (gcc 3.4.0 mit dem SDK 3) es gesetzt ist. Hier mal ein Beispiel wie ich es machen würde.

Für 'gcc' müsstest Du mal nachschlagen, welches Makro die Prozessorfamilie spezifiziert. Habe hier mal aus den Kopf zur Sicherheit alle genommen, die ich für m68k kenne.

code:
#if defined (__amigaos4__) || defined(__MORPHOS__) || defined(__AROS__)
 #define AMIGA
#else
 #if defined(__VBCC__) && defined(__M68K__)
  #define AMIGA
 #else
  #if defined(__GNUC__) && (defined(_M68000) || defined(__M68000) || defined(__mc68000))
   #undef AMIGA
   #define AMIGA
  #else
   #if  defined(__SASC) || defined(__MAXON__) || defined(__DCC)
    #define AMIGA
   #endif
  #endif
 #endif
#endif

#include <stdio.h>
#include <string.h>

int main( int argc, char **argv)
{
	#if defined(AMIGA)
	puts( "Running on an Amiga (alike) host.");
	#else
	puts( "Running on a non AMIGA (alike) host.");
	#endif
}


Für 'gcc' reichen solche Tests aber nicht auch; gibt ja auch Debian und NetBSD die unter m68k Prozessoren laufen. Da musst Du dann von Anfang an das Ausschlussverfahren anwenden...


Grüße


--
Stupid mistakes are always made by others -
we only make unavoidable errors
 
jolo   Nutzer

12.02.2012, 23:19 Uhr

[ - Direktlink - ]
Thema: Bedingungen im Initcode einer Library
Brett: Programmierung

@AGSzabo:

Zitat:
Ok. Soll ich nun im Open so lange warten bis Init ausgeführt wurde, oder mein Nachladen in Open machen?

Wenn Du Dir sicher bist, dass keine Exec-Tasks Deine Bibliothek öffnen, kannst Du es getrost in LibOpen durchführen. Bitte dann aber auch die entsprechende Bemerkung in die Endanwender-Dokumentation aufnehmen.
Ansonsten, in LibInit() erst eine SignalSemaphore erschaffen (statisch oder dynamisch, ist egal) und zwar vor dem Nachladen externer Dateien, dann InitSemaphore() aufrufen und direkt im Anschluss ObtainSemaphore(). Erst dann Zugriffe auf externen Datei starten. Wenn LibInit() beendet wird, die Semaphore mit ReleaseSemaphore() als unbelegt kenntlich machen.

In LibOpen() musst Du dann nur ganz am Anfang ein ObtainSemaphore() durchführen und bei Zugriff ein ReleaseSemaphore() durchführen. Das war's dann.


Zitat:
Wenn ich es im Open code mache, wird die Lib im Fall eines Fehlers nicht entfernt, oder?

Richtig.


Zitat:
Muss/darf ich dass dann genauso selber machen wie in Close/Expunge?

Ja, sollte funktionieren, da die Funktion OpenLibrary() sowieso im Forbid-Zustand ausgeführt wird.
 
jolo   Nutzer

12.02.2012, 16:48 Uhr

[ - Direktlink - ]
Thema: Bedingungen im Initcode einer Library
Brett: Programmierung

@AGSzabo:

Zitat:
Danke, also ausgeführt wird der Initcode nur 1x. Er ist nicht in der Open-Funktion, sondern in der Initfunktion. Oder kann es sein, dass der Initcode aus irgendwelchen Gründen nochmal aufgerufen wird? Ich bin auch schon den Initcode in Trace durch gegangen, da wird nach jedem Call, der Festplattenzugriffe aus löst, genug lang gewartet, bis er fertig ist. Oder nicht?

Zum Ersten: Unter Umständen wird der InitCode nochmals aufgerufen, leider erinnere ich mich nicht mehr daran, was dazu führt. Eine Möglichkeit wäre ein Bug in OS1.x und dass ich bis dato deshalb nach wie vor eine Sicherheitsabfrage mitführe.

Zum Zweiten: Warten bis Festplattenzugriffe vervollständigt wurden verbietet sich. Das Nachrichtensystem sollte hier einspringen, jedoch setzt das dann zwingend voraus, dass LibOpen() mittels einer Semaphore solange geblockt wurde, wie LibInit() noch nicht komplettiert wurde.

Auch wenn LibInit() scheinbar von dem aufrufenden Prozess aufgelöst wird, so ist dem doch nicht so. LibInit() wird vom Prozess "RamLib" ausgeführt, LibOpen() aber vom aufrufenden Prozess (z.B der Shell). Sollte hier die "RamLib" irgendwelche DOS-Funktionen ausführen müssen, z.B. dass Nachladen externe Dateien, wird der aufrufende Prozess, der noch keinen Zugriff auf LibOpen() bekommen hat, also nur in Lauerstellung stand (von vornherein verbietet der Prozess "RamLib" das Task-Switching), wieder Rechenzeit bekommen, weil der Prozess "RamLib" ein Wait() durchführen muss (IO-Opertionen bedienen sich des Exec-Nachrichtensystems), was dazu führt, dass das Task-Switching wieder erlaubt wird, und somit wird der Code in LibOpen() ausgeführt, jedoch geht dann das Unterfangen gründlich schief, weil der "RamLib"-Prozess den LibInit()-Code noch nicht vervollständigen konnte - er hängt ja noch in der Wait()-Funktion fest.

Kurz und bündigt:

RamLib -> LibInit()
Apps -> LibOpen, LibClose, LibExpunge und alle anderen LibraryVectorOffsets

wobei beim Ausführen des Prozesses "RamLib" das Task-Switching ausgeschaltet ist, nicht jedoch beim Ausführen der ordinären Funktionen.


@geit:

Zitat:
Libraries, device, settings, bilder etc nur in lib_open öffnen. lib_init ist nur zum Initialisieren globaler Resourcen wie Semaphoren gedacht.

Könnte man so machen und würde somit vielen Fehlerquellen aus dem Weg gehen, nur leider hat Commodore Amiga es leider anders vorgemacht, weil man Bibliotheken auch von einfachen "Exec-Tasks" aus öffnen können soll. Sollte dann ein einfacher "Exec-Task" eine Bibliothek öffnen, die in LibOpen() Disk-Zugriffe ausführt, wird es wieder einmal bunt, soll heißen, wählt man LibInit() zur Initialisierung solcher Dinge, ist sichergestellt, dass ein "DOS-Process" die Aufgaben erledigt.


@AGSzabo:

Zitat:
ich programmiere das in assembler. "Libbase in der Libbase selbst" verstehe ich nicht.

Du kannst die Adressen von irgendwelchen Bibliotheken innerhalb der Basis-Struktur Deiner Bibliothek halten oder aber auf Dateiebene als globale Adresse. Im ersten Fall kannst Du sie dann nur mittels indirekter Programmierung relativ zum Prozessor-Register "A6" adressieren, im zweiten Fall aber als absolute Adresse.

code:
1)
    STRUCTURE LibraryHeader,0
    ...
    APTR    lh_GfxBase
    ...
    LABEL   SIZEOF_LibraryHeader
   
_LibOpen ; A6 -> LibraryHeader
    ...
    move.l  A6,-(sp)
    movea.l lh_GfxBase(A6),A6
    ...
    ...
    movea.l (sp)+,A6
    ...
    rts

2)
_LibOpen ; A6 -> LibraryHeader
    ...
    move.l  A6,-(sp)
    movea.l _GfxBase,A6
    ...
    ...
    movea.l (sp)+,A6
    ...
    rts

    ...

_GfxBase
    dc.l 0

 
jolo   Nutzer

11.02.2012, 11:52 Uhr

[ - Direktlink - ]
Thema: HTMLView, gcc und fread, komische Dinge passieren
Brett: Programmierung

@gni:

Meine Erfahrung bezüglich verschiedener g++ Versionen ist, dass der Präprozessor von g++ 2.9.x toleranter arbeitet als der, der in den 3.x Versionen Verwendung findet. Z.B. erlaubt der alte Präprozessor das Einfügen von zwei aufeinanderfolgenden Doppelpunkten in Makro-Definitionen (z.B. um Klassenfunktionen zu spezifizieren), was unter 3.x Versionen nicht mehr funktioniert.
Zum anderen scheinen alle 3.x Versionen sich eher am ISO/ANSI C++ zu orientieren als die alten g++ 2.9.x Versionen, was dazu führt, dass man alte Quelltexte überarbeiten muss, sollen sie denn unter g++ 3.x kompiliert werden.

Ich selber habe im Dezember letzten Jahres die MuiPlusPlus Version von MorphOS (aber nicht die beigefügten Beispiele) auf OS3 für einen befreundeten Programmierer rückportiert, und zwar unter Verwendung des g++ 3.x, aber auch unter Beibehaltung der Kompatibilität zu MorphOS, was nach einiger Arbeit verlangte. Das initiale MuiPlusPlus wurde mittels g++ 2.9.x verfasst und wirft daher beim Kompilieren unter g++ 3.x massig Fehlermeldungen.

Das, was mich unter g++ 3.x nervt, ist eigentlich nur, dass dieser keine m68k-Register Bezeichner direkt in den Parameterlisten unterstützt, was eigentlich für das m68k-Amiga-API zwingend ist. Demnach kann man leider auch nicht auf "SDI_compiler.h" rückgreifen, um z.B. den Quellcode weitestgehend zu SAS/C kompatibel zu halten.

Bezüglich "extended assembler".
Ich spreche zwar verschiedene Assembler-Dialekte, aber diese eigenwillige GNU-Assembler Syntax in Verbindung mit dem Compiler ist nicht mein Ding, da weiche ich lieber auf "plain C" aus. :)
 
 
-1- 2 3 4 Ergebnisse der Suche: 108 Treffer (30 pro Seite)

Suchbegriffe
Schlüsselwörter      Benutzername
Suchoptionen
Nur in diesen Foren suchen
   nur ganze Wörter
Nur Titel anzeigen
alle Treffer anzeigen

.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1997-2019 by amiga-news.de - alle Rechte vorbehalten.
.