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: 110 Treffer (30 pro Seite)
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. :)
 
jolo   Nutzer

11.02.2012, 11:50 Uhr

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

Dein InitCode muss zum einen sicherstellen, dass er nur einmal initialisiert wird. Das kannst Du sicherstellen, indem Du eine Variable (z.B. ein Bibliotheksadresse) mit dem Wert null initialisierst und in Deinem InitCode gegencheckst. Ist der Wert nicht null, verlässt Du augenblicklich den InitCode. Zum anderen musst Du eine jegliche Initialsierung, welche Festplattenzugriffe unterliegt, mit einer Schutzvorrichtung ausstatten, z.B. mit einer Signalsemaphore, ansonsten wird der OpenCode schon ausgeführt/verlassen, bevor der InitCode komplettiert werden konnte.
 
jolo   Nutzer

05.02.2012, 23:12 Uhr

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

Verwendest Du OS3.x?
Wenn ja, hast Du das Problem, dass für Callback-Hooks die Parameter in den Prozessor-Registern übergeben werden müssen, was unter g++ 3.x nicht funktioniert. Hier musst Du auf C ausweichen um die Parameter aus den Registern zu lesen. Zudem werden Callback-Hooks u.U. nicht von Deinem Programm aufgerufen sondern von der Klasse selber. Somit solltest Du Dein Programm fürs große Datenmodell kompilieren oder aber mindestens das Attribut "__saveds" für solche Funktionen verwenden.
 
jolo   Nutzer

11.11.2011, 10:56 Uhr

[ - Direktlink - ]
Thema: Diverse WinUAE Probleme eines Powerusers
Brett: AROS und Amiga-Emulatoren

@Holger:

Ich habe leider Schwierigkeiten Deinen Gedankengängen zu folgen. Kannst Du diese bitte weiter ausführen, so dass ich sie zu verstehen lerne? Ich habe nämlich die Befürchtung, dass wir beide grundsätzlich verschiedene Sachen meinen.

Vorausschicken muss ich, damit Missverständnisse vermieden werden, dass ich eine Standard 104-Tasten Tastatur verwende, wie hier abgebildet, und dass bis auf die Pos1-Taste, ich alle anderen Tasten unter WinUAE 2.1 abfragen kann; unter WinUAE 2.3 klappt vieles leider nicht mehr.

Grüße

 
jolo   Nutzer

09.11.2011, 15:59 Uhr

[ - Direktlink - ]
Thema: Diverse WinUAE Probleme eines Powerusers
Brett: AROS und Amiga-Emulatoren

@Thore:

Zitat:
Bug oder eher missing Feature?
Womöglich war es damals nur nicht nötig mehr als 104 Tasten zu haben....


Ist ein Bug. Die gewöhnliche Amiga-Tastatur der damaligen Zeit hatte 96 Tasten, eine PC-Tastatur aber 101, später 104/105.
Mittels dem Device-Kommando KBD_READMATRIX sollte ein Abbild in einen privaten Puffer beliebiger Größe übertragen werden --- sollte!
Leider klappte das nicht mit einer anderen Anzahl als 13 Bytes (io_Length), 13 Bytes entsprechen aber 104 Tasten. Da Amiga-Tastaturen der damaligen Zeit jedoch nur 96 Tasten hatten, haben viele 12 als Wert für io_Length angegeben, was einen Fehler seitens des Keyboard-Devices (nicht implementiert) warf.
Zudem muss man um z.B. den Status der Capsable-Taste zu erfahren, nicht die gesamte Matrix erhalten, sondern nur die ersten 9 Bytes. Auch wurde zu Zeiten von 1.2/1.3 in der Dokumentation diese Anforderung (13 Bytes) mit keiner Silbe erwähnt. Ergo wirklich ein Bug.

Gruß
 
jolo   Nutzer

09.11.2011, 11:00 Uhr

[ - Direktlink - ]
Thema: Diverse WinUAE Probleme eines Powerusers
Brett: AROS und Amiga-Emulatoren

@Holger

Zitat:
Auf dem Amiga gibt es ja auch keine Pos1-Taste.

Richtig, auf einem Classic Amiga gibt es wirklich keine Pos1- (Home-) Taste, jedoch kann man sofern die Voraussetzungen stimmen, eine Tastatur verwenden die weitaus mehr Tasten anbietet als solche mit dem gewöhnlichen 96-Tasten Layout. Ich verwende seit Jahren solche Tastaturen unter Amithlon und WinUAE und kann sie auch anhand der Keyboard-Matrix leicht abfragen, jedenfalls ab OS2. Unter OS1.x gibt's 'nen ollen Bug, wobei die Funktion ReadKeyboardMatrix() bzw. KBD_READMATRIX mit einem Puffer der exakt 13 Bytes groß ist, aufgerufen werden muss, was bedeutet, dass unter OS1.x nur Tastaturen mit maximal 104-Tasten abgefragt werden können. Wie dem auch sei, die Funktionstasten "F11" und "F12", sowie "Ende", "Einfügen", "Bild-runter", "Bild-rauf", "Druck", "Pause", und so fort kann ich alle ohne Probleme unter OS3.x abfragen (KBD_READEVENT) und benutzen; beim Drücken der Pos1-Taste übermittelt WinUAE aber keinerlei Keyboard-Matrix noch den RawKey-Code, es ist so als ob die Taste nicht gedrückt würde, warum, weiß ich allerdings nicht.

Zitat:
Die kann also nur funktionieren, wenn Du ihr von Hand eine Funktion zuweist, die Du als richtiges Äquivalent erachtest.

Ich bin unschuldig und halte mich an Spezifikationen. :)

Hier einen kleinen Auszug für die entsprechenden RAWKEY-Codes.

code:
/* OS 4 and old declaration from '96 */
#define RAWKEY_INSERT		0x47
#define RAWKEY_PAGEUP		0x48
#define RAWKEY_PAGEDOWN		0x49
#define RAWKEY_F11		0x4B
#define RAWKEY_PRINTSCR		0x6D
#define RAWKEY_BREAK		0x6E
#define RAWKEY_F12		0x6F
#define RAWKEY_HOME		0x70
#define RAWKEY_END		0x71
...
#define RAWKEY_HOME_ALT		0x75
#define RAWKEY_END_ALT		0x76
#define RAWKEY_PAGEUP_ALT	0x77
#define RAWKEY_PAGEDOWN_ALT	0x78
#define RAWKEY_PRINTSCR_ALT	0x7B
...


und so weiter. Sind die Standardbelegungen die seit 1996 spezifiziert wurden, mit den Alternativen für AmigaOS4.

Wie auch immer, mit dieser einen Unzulänglichkeit (Pos1) könnte ich gut leben, was mir allerdings gehörig den Spaß vermasselt, ist dass das Hochkomma nicht mehr seinen angestammten Platz einnehmen kann, noch das für mich äußerst wichtige Beenden einer CLI-Eingabe mittels CTRL-Backslash nicht mehr durchgeführt werden kann. Unter WinUAE 2.1 funktioniert alles so wie es soll, bis auf die Probleme mit der Pos1-Taste, die sind seit den Anfängen drin. Daher benutze ich jetzt für reguläre Arbeiten nicht mehr die neueren WinUAE-Versionen.

Grüße

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

05.11.2011, 11:02 Uhr

[ - Direktlink - ]
Thema: Diverse WinUAE Probleme eines Powerusers
Brett: AROS und Amiga-Emulatoren

Zitat:
1. Nach längerer intensiver Benutzung fängt die Maus an zu Springen.

Kann ich bestätigen. Seit WinUAE 2.3 passiert das sporadisch. Ich vermute, dass die USB Maus/Tastatur Handhabung unter WinUAE dafür verantwortlich ist.

Zitat:
2. Shift, Capslock, Alt etc. bleiben des öfteren hängen.

Kann ich auch bestätigen, jedoch hilft hier im Gegensatz zu Deiner Konfiguration das Drücken der betreffenden Tasten, dann arbeiten diese wieder wie gewöhnlich.

Zitat:
3. Wenn ich zum Windows Desktop wechsele, und WinUAE im Hintergrund aktiv bleibt, dann empfängt er zwar keine Keyboard Events mehr, aber Maus Events und Clipboard Events (ich nutze Shared Clipboard).

Kann ich bestätigen.

Zitat:
5. Im Fullscreen Modus braucht WinUAE beim Umschalten eine gefühlte Ewigkeit.

Kann ich nicht bestätigen; das Umschalten geschieht augenblicklich. Gleiche Auflösung und gleiche Bit-Tiefe wie der Windows-Desktop.

Hinzufügen kann ich noch an Problemen, dass eine deutsche Tastaturbelegung mittels USB-Tastatur nicht alle Tasten inklusive deren Codes der Amiga-Seite zur Verfügung stellt, so dass ich z.B. das Hochkomma auf ALT-Ä legen musste, anstatt auf SHIFT-#. Zudem erreiche ich den Dead-Key für CTRL-Backslash nicht mehr, so dass ich eine CLI-Eingabe nicht mehr beenden kann, als auch dass die Pos1-Taste nicht funktionsfähig ist. Ob es sich dabei um Unvermögen meinerseits handelt eine meinen Ansprüchen entsprechende WinUAE-Konfiguration auf die Beine zu stellen oder durch Fehler in WinUAE verursachtes Fehlverhalten, kann ich abschließend nicht sagen, jedoch benutze ich ob dieser Unzulänglichkeiten nach wie vor nur WinUAE in der Version 2.1, da gibt es bis auf die Pos1-Taste keine Probleme dieser Art.

Grüße

 
jolo   Nutzer

26.07.2011, 11:21 Uhr

[ - Direktlink - ]
Thema: Anfänger: DOS-Programm auf den Classic portieren
Brett: Programmierung

@Dr_Chaotica:

Zitat:
Mittlerweile habe ich noch ein bisschen rumprobiert, komme aber nicht weiter.
Der Sourcecode an sich ist nicht problematisch, weil das Programm selbst nicht auf Hardware zugreift, keine GUI hat und nur ein File verändert.


Wenn es ein MS-DOS-Programm ist, ist es problematisch (unter DOS verstehe ich ein MS-DOS Programm). MS-DOS ist so ziemlich das Inkompatibelste was man heutzutage zum schnellen Portieren vorfinden kann. MS-DOS Aufrufe muss man auf die C-Std-Lib ummünzen, evtl. musst Du auch noch auf die POSIX-API zurückgreifen. Beides ist möglich aber nur mit Aufwand verbunden.


Zitat:
Mein Hauptproblem ist vbcc selbst.
Ich habe die Binaries für OS3 und die Target-Icludes für OS3 installiert.

Nun crasht der Befehl vc immer dann, wenn ein bestimmtes File (eine .asm-Datei) aus t: ausgelesen werden soll. Offenbar liegt es daran, dass vc oder vbccm68k auf ein Verzeichnis "t: statt t: zugreifen will, was wohl an einem Platzhalter %s in der Config-Datei liegt. Weiß jemand, was ich da eintragen soll, damit vc keine Anführungszeichen setzt oder erwartet?


Welche Version von 'vbcc' benutzt Du? Aktuell ist die Version 0.9b (19.05.2011), die aber noch nicht auf Frank seiner Homepage zu finden ist. Leider ist die Version 0.9a, die auf der Homepage von Frank bereitgestellt wird, nicht zu empfehlen, da diese etliche Fehler beinhaltet, die aber erst beim Ausführen der Datei zum Tragen kommen, also nicht beim Kompilierungslauf (mit zwei Ausnahmen).
Einfach Frank eine E-Mail zukommen lassen und um die aktuelle Version bitten. Alternativ könnte ich auch ein Archiv mit den neuen OS3 Binaries/Configs bereitstellen; muss aber dafür erst einmal Franks OK haben, da Frank schon an dem neuem Release arbeitet.


Zitat:
Und dann noch dies: Wenn ich die Befehle von Hand eingebe, bekomme ich zuerst eine .asm-Datei, danach eine .o-Datei und letztere müsste dann mit vlink zum Executable werden. Da bringt vlink aber haufenweise Fehlermeldungen namens "unexpected reference" (bin mir nicht mehr ganz sicher, wie der genaue Wortlaut ist). Was bedeutet dies?

vc +aos68k -c99 test.c -o ram:test -lvc

Dieser Aufruf muss eine ausführbare Datei in der RAM-Disk erstellen, keine ".asm" oder ".o" Datei. Wenn ein interner Compiler/Assembler Fehler auftritt, so wie bei alten 0.7x/0.8x Versionen von 'vbcc', so bleiben die *Leichen*, sprich, die temporären ".asm" oder ".o" Dateien übrig...


Poste mal bitte die Fehlercodes.

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

13.12.2010, 19:34 Uhr

[ - Direktlink - ]
Thema: 68K Assembler
Brett: Programmierung

@Holger:

Zitat:
weil ältere Beispielprogramme den Output-Handle immer direkt aus der Prozessstruktur ausgelesen haben.

Ja, das kommt mir auch sehr bekannt vor, aber ich meine es war nicht mittels der Prozess-Struktur sondern anhand der Global-Vector-Table, die vom BCPL-DOS jedem Prozess zugänglich gemacht wurde. Hieß das Ding wirklich so? Ich kann mich nicht mehr genau erinnern. Jedenfalls waren die 20 Funktionen des BCPL-DOS, die als API nach außen geführt wurden, nur eine kleine Menge verglichen mit den Funktionen, die man über die Global-Vector-Table erreichen konnte. Mit OS 1.4 (beta 2.0), wurden dann diese Funktionen nach außen gelegt, und man musste nicht mehr Assembler benutzen, um diese Funktionen zu benutzen (sie benutzten nicht die herkömmlichen Register, z.B. wurde D1 als Rückgaberegister benutzt und nicht D0 sowie diese komischen Offsets als Einsprungadressen). Ist aber schon Ewigkeiten her, dass man diese benutze (Mitte der 1980er Jahre), auch weil mit jeder Neuerung des DOS die Tabellenoffsets sich änderten (nur nicht zwischen Kickstart v33 und v34).


@fisch08:
Habe eine kleine Demo auf "www.amimedic.de" hochgeladen (HelloWorldGUI). Es ist assemblierbar mit 'vasm', PhxAss und Devpac. Kommandozeilenaufrufe sind im Quelltext abgebildet.


Grüße
 
jolo   Nutzer

11.12.2010, 19:47 Uhr

[ - Direktlink - ]
Thema: 68K Assembler
Brett: Programmierung

@DieterG:

Zitat:
Ich habe nie behauptet, vasm hält sich nicht an den Motorola-standard.

Du stellst aber Behauptungen auf, die so missverständlich formuliert wurden, dass ich zu Schlussfolgerungen kommen muss, die rein gar nicht Deinen Aussagen entsprechen.


Zitat:
...kann aber mit vielen üblichen Macros nicht umgehen []

Hättest Du geschrieben, dass ASM-Pro Makros erlaubt, die weit über das hinaus gehen was Motorola spezifiziert hat sowie von anderen Assemblern erst gar nicht unterstützt werden, so dass man nur die K-Seka-Klone benutzen kann, um solch verfasste Quellcodes zu übersetzen, hätte ich bestimmt nicht nachgefragt.


Zitat:
Und selbst der wurde ja schon in der Zeit der weiterentwicklung vom 68000 zu höheren Prozessoren von Motorola selbst geändert:-)

Nee, nur erweitert, bedingt durch die 68020 Adressierungen wie Du weißt. :)


Zitat:
Das Hauptproblem des vasm scheint zu sein, das er sowas wie "lokale Labels" nicht unterstützt, was bedeutet jeder verwendete Label ist auch in der Symboltable enthalten und darf nur einmal verwendet werden, somit muss z.b. jeder loop anders heissen, das erschwert alles.

Innerhalb von Makros?
LabelName@
Entspricht somit der offiziellen Motorola m68k Notation.


Oder innerhalb des Quellcodes auf Dateiebene?
n$
Auch offiziell...

Es geht auch in neueren 'vasm' Versionen mittels:
.LabelNamen
was aber nur eine Devpac Variante ist aber von anderen Assemblern abgekupfert wurde.


Wie definieren die K-Seka-Klone lokale Bezeichner, dass 'vasm' sie nicht handhaben kann (darf?)?


Zitat:
Zum vasm: versuch mal einer der vielen ASM-Sourcecodes vom Aminet mit diesem ohne Modifikation zu assemblieren, bei den meisten wird das scheitern.

Da magst Du Recht haben, die Frage die sich mir aber stellt ist, ob es an 'vasm' oder am Autor des betreffenden Quellcodes liegt, der *nicht* die offizielle Schreibweise benutzte.

Ich habe selber K-Seka, C-Seka sowie MasterSeka Ende der 1980er und Anfangs der 1990er Jahre verwandt, bis ich Anfang 1991 sporadisch Devpac 2 benutzte um Vollendends in 1992 auf Devpac 3 umstieg. Dass meine damaligen Quellcodes nicht mehr von Devpac akzeptiert wurden, lag nicht an Devpac 2/3 sondern an (den) K-Seka (-Klonen). Dafür habe ich dann einen Konverter geschrieben, der den K-Seka Syntax, inklusive Makro-Schreibweise, in die offizielle Motorola Syntax umwandelt.
Lange Rede, schwacher Sinn: Es gibt eine offizielle Norm an die man sich halten sollte, wenn man sicherstellen will, dass ein Quellcode von verschiedenen Assemblern akzeptiert wird. Verwendet man spezielle Merkmale eines Assemblers, sollte man nicht dem Autor des fremden Assembler Unterlassung/Nachlässigkeit unterstellen, sondern sich selber fragen, ob man zwingend solche Besonderheiten nutzen muss, wenn man seine Quellcodes offen legt.

Wenn ich Dich richtig verstanden habe, so lassen sich viele Assembler Quellcodes die im Aminet freigegeben wurden nicht mittels 'vasm' assemblieren, weil sie auf einen bestimmten Assembler zugeschnitten sind. Deshalb aber 'vasm' als nicht kompatibel abzustufen halte ich für arg unfair dargestellt (gelinde gesagt). ;)


Zitat:
Zudem hat er die C-typischen Nachteile alle übernommen, was auch nicht Motorolastandard ist.

Dir ist schon klar, dass 'vasm' von Dr. Volker Barthelmann ins Leben gerufen wurde, um einen portablen Assembler für verschiedene Hosts und Targets für seinen C-Compiler zu erhalten, und sich nicht nur auf m68k beschränken zu müssen. Soweit ich weiß, benutzte er anfangs Frank Willes PhxAss (m68k Assembler) und PhxLink (AmigaDOS Linker). Erst nachdem sich Frank Wille 'vasm' angenommen hat wurde aus 'vasm' ein universeller, Standards entsprechender und vielseitiger Assembler, wobei 'vasmm68k-mot' (der m68k vasm) nach wie vor noch in der Lage sein muss, den von 'vbcc' erstellten Code zu übersetzen, was nicht zuletzt ein gewisses Maß an Abwärtskompatibilität (Altlast!) zu PhxAss beinhaltet. Nichtsdestotrotz kann man ( zumindest ich ;) ) klaglos Devpac erstellte Quellcodes mit 'vasmm68k-mot' übersetzen.


Zitat:
Und was nützt mir das strikte halten an den Motorolastandard, wenn ich doch verscheidene Plattformen als ziel unterstütze ? Nicht alle Prozessoren sind von Motorola !

Kannst Du mir mitteilen, was Du damit meinst?
1) Was sind verschiedene Plattformen für Dich?
2) Welche Auswirkungen auf die Syntax hat eine in Linzenz gefertige 680x0 CPU?

Irgendwie verstehe ich Dich nicht so ganz.


Zitat:
Also wie gesagt, für kleinere Projekt ist der vasm durchaus geeignet, aber bei grösseren ist schon allein die labelbennenung oder das fehlen eines internen versions oder datummacros nervig. Eben wie in C, muss man alles extern selber machen, der ASM-Pro z.B.unterstützt einen da viel besser

Erstens, in C ist es einfacher gelöst, einfach '__DATE__' spezifizieren.
Zweitens hat es je nach Geschmack mehr Vor- oder Nachteile, wenn eine automatische Versionskontrolle ausgeführt wird. Ich persönlich mag überhaupt keine automatische Versionsänderung ohne meine explizite Angabe. Wie gesagt, andere mögen es, aber eben nicht jeder.
Drittens, ob ein Assembler für größere oder kleinere Projekte von Vorteil ist, liegt bestimmt nicht an solchen Details, sondern ob der Assembler imstande ist, in einer akzeptablen Zeit den Quellcode zu übersetzen. Bei größeren Projekten wird man sowieso mehrere Module schreiben, die man anschließend 'linkt' und nur die veränderten Dateien neu assemblieren.
Da 'vasm' sowohl direkt ausführbaren Code also auch linkbaren Code generieren kann als auch die Übersetzungszeiten akzeptabel sind, kann 'vasm' sowohl für kleinere als auch für große Projekte verwenden.

Anbei: :)
Wäre ich tippfaul, so würde ich für kleine Projekte einen Assembler mit IDE vorziehen, weil dies bequemer für mich wäre, als über die Kommandozeile den Assembler aufzurufen. Erst bei größeren Projekten geht es sowieso nicht mehr ohne den Umweg über die Kommandozeile um ein Skript oder ein 'makefile' aufzurufen, da meines Wissens nach keine Assembler-IDE eine 'Make'-Umgebung nachbildet.


Zitat:
Was ich aber eigentlich sagen wollte, für einen der sich relativ neu wieder mit dem Thema 68k-Assembler beschäftigen will, sind schon allein die meisten alten Bücher, Kurse, Anleitungen und Beispielcodes besser auf einem Sekaclone nachzuvollziehen, da diese meistens älter sind, und es da einfach noch kein vasm gab.

Aber es gab eine Norm, dem der MetaComCo Assembler voll entsprach, und dieser wurde dem Entwicklerpaket beigefügt, bzw. man konnte diesen nachbestellen (Kickstart 1.1/Kickstart 1.2). K-Seka hatte eine sehr große Fan-Gemeinde bei den Hobby-Programmierern, die ohne das Betriebssystem auskamen, nicht zuletzt wegen seiner rasanten Assemblierungsgeschwindigkeit. Leider entsprach er weder den Motorola Spezifikationen noch bot er einen Link-Modus an, was ihn für größere Projekte disqualifizierte. Erst mit den Klonen kam sowas wie Kompatibilität auf. Leider erbten diese Klone aber auch die schlechten Eigenschaften, z.B. 'blk' statt 'dcb' oder 'An,bd' anstatt 'bd,An'.
Ich habe mehrere 68k Assembler Bücher hier, aber nur eines benutzt den K-Seka Syntax, und zwar jenes, welches ohne das Betriebssystem die Hardware direkt anspricht, zudem kann ich die Quelltexte dieses Buches keinem empfehlen, da alle möglichen Optimierungsmöglichkeiten außer Acht gelassen wurden sowie mittels 'clr.w' Hardwareregister gelöscht wurden, wobei jeder weiß, dass das unter einer 68000er fatale Folgen hat, weil ja auch ein Read-Zyklus vor dem Löschen durchgeführt wird. Bei Nur-Schreibregister wird's dann bunt... ;)
Um es kurz zu machen: Über die Güte eines Quellcodes sagt der verwendete Assembler nichts aus.


Um meine Sichtweise der Dinge mal darzulegen:
Ich habe nichts gegen die Verwendung von Assembler XYZ einzuwenden, jedem das seine, was ich aber nicht stehenlassen will, sind Behauptungen, bei denen Ursache und Wirkung meinem Erachten nach vertauscht werden.
Werden spezielle Charakteristiken eines Assemblers verwendet, darf man nicht mokieren, dass der betreffende Quellcode sich nur mit diesem Assembler übersetzen lässt. Z.B. erlauben Devpac und 'vasm' das Weglassen des Semikolons vor Kommentaren; andere Assembler erlauben es nicht. Will man seinen Quellcode veröffentlichen, sollte man die Notation verwenden, die alle Assembler verstehen, demnach sollte man das Semikolon verwenden. Hier einfach behaupten, dass andere Assembler nicht kompatibel genug wären, wäre zu kurz gegriffen.
Bevor ich in der Vergangenheit Quellcodes, die mit Devpac erstellt wurden offen gelegt habe, wurde mittels PhxAss und SNMA gegengeprüft, ob sie sich unverändert assemblieren ließen. Andere hätten auf die gleiche Idee kommen können und somit anderen viel Arbeit erspart.


Grüße
 
jolo   Nutzer

10.12.2010, 13:50 Uhr

[ - Direktlink - ]
Thema: 68K Assembler
Brett: Programmierung

@DieterG:

Das mit den Makros musst Du mir mal erklären! :)
Inwiefern ist 'vasm' inkompatibel zur Motorola Spezifikation bezüglich Makros? Denn nur diese offizielle Spezifikation wird von 'vasm' unterstützt. Die halbgare, von K-Seka eingeführte Syntax wird nicht und wurde von keinem anderen Assembler als K-Seka und deren Klone unterstützt.
Der de facto Standard und die Referenz für die Assemblerprogrammierung unter AmigaOS war Devpac 3.x; dieser Assembler hielt sich strikt an die von Motorola festgeschriebene Syntax - und das Gleiche gilt für 'vasm'.

Das gerade 'vasm' nur für kleine Projekte sinnvoll erscheint, ist nicht ganz Dein Ernst, oder?
Wenn es rein um Hardwarebanging geht kann man gut auf K-Seka und Klone zurückgreifen; wird man aber offiziellen Quellen folgen - und systemkonforme Programme oder Funktionsmodule erstellen wollen, greift man gewöhnlich auf Include-Dateien zurück, die noch zu Commodore-Amigas Zeiten erstellt wurden und hundertprozentig der Motorola Spezifikation unterliegen, und meine persönliche Erfahrung mit K-Seka und Klonen ist, dass eben jenes es sind, die Probleme damit haben.

Welchen Assembler man verwendet, hängt zum Großteil vom persönlichen Geschmack und Einsatzbereich ab. Ich persönlich bevorzuge Devpac und 'vasm, wobei 'vasm' seinesgleichen derzeit sucht, oder kannst Du mir irgendeinen Assembler nennen, der außer 'vasm' als Cross-Assembler verwendbar wäre? 'gas' hat seine eigene Syntax wie Holger schon geschrieben hat und scheidet damit aus. Zudem läuft 'vasm' auch ohne irgendwelche Tricks unter anderen Betriebssystemen (keine UNIX-nachgebildete Umgebung von Nöten oder einen AmigaOS kompatiblen 68k-Emulator), sei es nun Atari OS, BSD, Linux, MacOS oder Windows.

Komischerweise haben wir dank Frank Wille mit 'vasm' einen aktuellen Assembler der noch dazu gepflegt wird und verschiedenste Architekturen unterstützt, sei es nun CPUs oder Betriebssysteme, aber bei Hobby-Programmierern hält sich nach wie vor noch das Gerücht, dass ein K-Seka Klon kompatibler wäre, was ich jetzt mal ins Reich der Märchen verbanne. :)

Wie gesagt, Du magst ASM-Pro, ich mag 'vasm', aber solche Behauptungen wie:

"...also eher was für kleinere Projekte"

kann ich einfach nicht stehen lassen. :)


Grüße
 
jolo   Nutzer

24.10.2010, 13:16 Uhr

[ - Direktlink - ]
Thema: scheinbaren doppelten content vermeiden (SEO)
Brett: Programmierung

Zitat:
seit ein paar tagen nutze ich die funktionalität mittels .htaccess und einer index.var zu anderen sprachen in subdirectories umzuleiten. zB wird domain.de/ bei der browsereinstellung "de" nach domain.de/de/start.html umgeleitet.

Hmmm, meines Wissen nach (bin kein Apache-Experte) sollte man nicht aus "domain.de/index.html" "domain.de/de/start.html" machen, sondern "domain.de/start.de.html" bzw. "domain.de/start.en.html". Somit auch keine Unterverzeichnisse für die Root-Datei. Verweisende Dateien können natürlich in Unterverzeichnisse bleiben/wandern.

Beispiel:

code:
# .htaccess

Options +MultiViews
AddLanguage de .de
AddLanguage en .en
LanguagePriority de en

# Einstellungen für alternative Inhalte mit Apache 2.x
AddHandler type-map .var

# Deklaration der Dateien für die Pseudo-Index-Funktion
DirectoryIndex start.var



code:
# start.var

URI: start

URI: start.de.html
Content-type: text/html
Content-language: de
Description: "Das deutsche Original des Dokuments"

URI: start.en.html
Content-type: text/html
Content-language: en
Description: "English translation of this document"



Hier werden dann die Daten zwischen Browser und Apache-Server ausgetauscht, so dass bei einem Aufruf von "domain.de" entweder "start.de.html" oder "start.en.html" an den Browser weiter gereicht wird. Mit Unterverzeichnissen habe ich noch nicht experimentiert, sehe dazu auch keine Veranlassung.

Aus Kompatibilitätsgründen sollte auf den Standard "DirectoryIndex" "index" (index.var) innerhalb von ".htaccess" verzichtet werden, weil es leicht den Server verwirren kann; es könnten ja noch andere Dateien namens "index.nnn", vorhanden sein. Woher soll dann der Server wissen, welche Datei es weiterreichen soll? Daher ist eine explizite Angabe besser.

Anbei, ob die Google-Suchmaschine zwischen mehrsprachigen Sites differenziert, wage ich zu bezweifeln. Die Google-Suchmaschine versucht meinem Wissen nach in Abhängigkeit mit der Domain-Adresse eine Seite zu durchforsten. Demnach, bei einer ".de" Domain, immer nur den deutschen Inhalt, und nicht irgendeinen anderen.


Grüße
 
jolo   Nutzer

24.05.2010, 18:46 Uhr

[ - Direktlink - ]
Thema: SDI-Makros und vbcc-m68k
Brett: Programmierung

@gni:

Zitat:
Dito. Dennoch solltest Du Dein (oder eben mein :) System nicht als repräsentativ ansehen.

Mache ich bestimmt nicht. Ich hab' ja geschrieben dass es ein unschönes Workaround ist. :-}

Zitat:
Es wäre interessant zu wissen, ob __M68K__ schon immer das Architektur #define von VBCC war.

Frank kann dies definitiv beantworten. :)


Zitat:
Wenn es eine korrekten Weg gibt und man den auch kennt, dann sollte der auch benutzt werden. Alles andere fällt einem früher oder später (meist früher :) immer auf die Füße...

LOL, stimmt, aber siehe unten...


Zitat:
Kein Compiler erzählt irgendwas über sein Host-System, denn welchen Sinn sollte das haben? Alle #defines beziehen sich ausschließlich auf das Zielsystem.

Das ist der Unterschied zwischen Dir und mir: Du weißt sowas, ich kann nur Vermutungen anstellen. Dementsprechend will ich auch nicht Hand an SDITools legen, sondern das sollen Programmierer mit Deiner Erfahrung tun. Ich würde es höchsten verschlimmbessern. :)
Ich bleib' lieber auf der sicheren Seite und melde Fehler die dann andere beheben können.


Grüße
 
jolo   Nutzer

21.05.2010, 00:33 Uhr

[ - Direktlink - ]
Thema: SDI-Makros und vbcc-m68k
Brett: Programmierung

@gni:

Zitat:
Nur, im Programm selber wird dann wieder auf die PPC-Variante zurückgegriffen. Was da genau schief geht, kann ich nicht noch nicht sagen.
Zitat:
Mysteriös. Werde ich bei Gelegenheit mal testen.


Des Rätsels Lösung liegt in "SDI_hook.h", welches einmal einen "generischen" Abschnitt, zum anderen aber einen reinen m68k Abschnitt definiert. Jetzt, nachdem ich mit den "alten" Dateien herum experimentiert habe, kann ich sagen, dass "SDI_compiler.h" fehlerfrei war und demnach auch die neue Version ist.
Nur "SDI_hook.h" ist in Verbindung mit 'vbcc', wobei der Ziel-Prozessor höher als 68000 gewählt wurde, fehlerhaft.


Zitat:
Ich spezifiziere immer eine 68020 als Zielversion. Demnach testet "(defined (__VBCC__) && !defined(__PPC__))" korrekt auf 'vbcc' ungleich PPC-Backend, was dann hier bedeutet, dass es sich um m68k handelt.
Zitat:
Nein. Dann weißt Du nur, das es _nicht_ PPC ist. Du willst aber wissen ob es m68k ist und das testet Du bei VBCC mit __M68K__ (bei GCC wäre es __mc68000 und bei SAS/C ist es _M68000).


Richtig. Ich habe aber geschrieben, dass es *hier* bedeutet, dass es sich um m68k handelt. Ich habe ausschließlich PPC und m68k Backends für 'vbcc' installiert.


Zitat:
Du implizierst, das es 68k ist und diese Schlußfolgerung ist nicht zwangsläufig richtig.

Ich weiß. Allerdings gibt es kein offizielles i686 Backend von 'vbcc', welches AROS unterstützt. Käme es jemals zustande, müsste "SDI_compiler.h" auch modifiziert werden.
Da die SDITools aber ausschließlich für AmigaOS (m68k), AROS (i686, x86_64, PPC), MorphOS und AmigaOS4 (PPC) gedacht sind, ist dies aber eher hypothetischer Natur, obschon Du natürlich Recht hast und es besser wäre, von Anfang an so etwas zu berücksichtigen. Jedoch müsste man dann aber schon bei "SDI_compiler.h" ansetzen und nicht erst bei "SDI_hook.h"...


@whose:

Zitat:
So, wie sich das für mich liest, ist sein Problem das, daß es möglicherweise Compiler geben könnte, die blöd genug gebaut wurden, um Host und Target nicht eindeutig trennbar anzugeben.

Exakt das meinte ich. :)
Ich kenne/benutze nur StormC v3; 'gcc' für AmigaOS, AROS und Linux; MaxonC++ sowie vbcc für AmigaOS, MorphOS und AmigaOS4 - und Anleitungen lese ich nur bei Bedarf.
Demnach traue ich mir nicht zu, zu sagen, was andere Compiler so an vordefinierten Symbolen bereitstellen.


Grüße
 
jolo   Nutzer

20.05.2010, 11:22 Uhr

[ - Direktlink - ]
Thema: SDI-Makros und vbcc-m68k
Brett: Programmierung

@damato:

Zitat:
Die neueste Version der SDI_compiler.h hat die verison 1.32. Die aktuellsten Versionen davon sind immer unter folgendem CVS repository frei verfügbar:

http://sditools.cvs.sourceforge.net/viewvc/sditools/sditools/headers/


Danke! :)
Werde diese herunterladen und schauen ob sich etwas geändert hat beim Kompilieren mit 'vbcc'.


Zitat:
Natürlich würden wir uns freuen wenn du deine Änderungen irgendwo als komplette Dateien veröffentlichen können sodass wir diese in einer neuen version der SDI headers mit aufnehmen können.

Im Moment ist es ein unschönes Workaround - und ich will die betreffenden Dateien nicht verunstalten. Zudem muss ich jetzt erst einmal intensive Tests machen, weil Guido und Gunther der Meinung sind, es könnte gar nicht sein bzw. meine eingefügte Abfrage wäre falsch.

Vorausschicken muss ich aber, dass das betreffende Programm seit Oktober letzten Jahres nicht mehr fehlerfrei mit 'vbcc' erstellt werden konnte; ich bis dato aber immer von einem Fehler im Compiler ausgegangen bin. Nachdem jetzt diverse Fehler in 'vbcc' ausgemerzt wurden, war ich mir nicht mehr so sicher und habe das komplette Programm disassembliert. Dabei ist mir dann die Argumentübergabe über den Stack ins Auge gefallen, so dass ich "SDI_compiler.h" und "SDI_hook.h" als mögliche Ursache in Betracht gezogen habe. Nach einigen Tests und Änderung dieser lief das Programm wieder einwandfrei - ohne Änderungen am Programm selber.


@Geit:

Zitat:
Also ich hatte mit den SDI Dateien und VBCC nie Probleme.

Das streite ich auch nicht ab. Dass ich aber hin und wieder Probleme mit den SDI-Makros hatte, habe ich Dir ja auch in der Yahoo-Mailing-Liste mitgeteilt und Dich gebeten, diese zu beheben. Ist aber schon lange her (2007?).


Zitat:
Ich nutze sie für alle meine Projekte ausgiebig. Installer, MMKeyboard, Meridian, IRCom, ...

Sowohl für 68K also auch für PPC und AROS_x86.


Ich widerspreche dem auch nicht, nur funktionierten hier die SDITools nicht unter 'vbcc' v0.9a, und dabei war es egal ob es sich um die 'vbcc' Version von Oktober letzten Jahres handelt oder um die Version von Mitte April diesen Jahres.


@gni:

Zitat:
Das angegebene SDI_compiler.h sieht aber korrekt aus.

Ja, und komischerweise wird das REG-Makro ja auch definiert. Nur, im Programm selber wird dann wieder auf die PPC-Variante zurückgegriffen. Was da genau schief geht, kann ich nicht noch nicht sagen.
Habe demnach als Quick-Workaround (okay, Hack :) ) ein "#undef" und anschließendes "#define REG..." eingebaut.

Zitat:
Hast Du geprüft, ob VBCC wirklich durch den __VBCC__ Block geht?

Ja, mittels "#error" Ausgabe veranlasst, um zu sehen, ob der für 'vbcc' vorgesehene Block angesprungen wird.


Zitat:
!__PPC__ kann nicht richtig sein. Wenn dann "&& defined(__M68k__)". Ich hätte jetzt allerdings auch erwartet, das __M68000 immer definiert ist, laut .pdf ist das aber anscheinend nicht der Fall, müßte man prüfen.

Ich spezifiziere immer eine 68020 als Zielversion. Demnach testet "(defined (__VBCC__) && !defined(__PPC__))" korrekt auf 'vbcc' ungleich PPC-Backend, was dann hier bedeutet, dass es sich um m68k handelt. "__M68000" ist wirklich nur dann unter 'vbcc' gesetzt, falls das Zielmodell eine 68000 ist.
Und ja, in der finalen Version von "SDI_hook.h" sollte man "__M68K__" verwenden. Da aber SDI viele Compiler unterstützt, bin ich mir nicht sicher, ob nicht irgendein Compiler auch "__M68K__" verwenden könnte, und zwar zur Identifizierung des Host-Modells, was dann Probleme mit sich bringt. Demnach denke ich, dass man momentan unter Verwendung von "(defined (__VBCC__) && !defined(__PPC__))" auf der sichereren Seite ist. Wie gesagt, wenn kein Compiler außer 'vbcc' von "__M68K__" Gebrauch macht oder diese Compiler "__M68k__" nur für das Target-Modell spezifizieren, kann man "__M68K__" verwenden. Ich bin hier aber schlichtweg überfragt.
Vielleicht kannst Du schon sagen, ob SAS/C und 'gcc' "__M68K__" nicht verwenden?
Und eine Abfrage wie "(defined (__VBCC__) && defined(__M68K__)) sieht in den jetzt sehr aufgeräumten SDI-Makros einfach unschön aus.


Nachtrag:
Habe die von Jens gepostete URL benutzt um die neuste Version von SDITools herunterzuladen.
Nachdem ich ausschließlich "SDI_hook.h" um eine "__M68K__" Abfrage erweitert habe, funktioniert es jetzt einwandfrei.
Aber wie oben schon beschrieben, habe ich Bedenken bezüglich "__M68K__". Es muss sichergestellt sein, dass kein Compiler dies benutzt um den Nutzer zu informieren, welche HOST-CPU-Familie benutzt wird, falls überhaupt ein Compiler existiert, der so etwas unterstützt...


Grüße
 
jolo   Nutzer

19.05.2010, 21:43 Uhr

[ - Direktlink - ]
Thema: SDI-Makros und vbcc-m68k
Brett: Programmierung

Dies ist nur eine Information für diejenigen unter uns, die SDI-Makros in Verbindung mit 'vbcc m68k' verwenden.

Wer mittels 'vbcc' für m68k MUI-Programme erstellt, oder Argumente in Registern übermittelt und dafür "SDI_hook.h" oder "SDI_compiler.h" benutzt, sollte sehr, sehr vorsichtig sein.
Mir ist heute aufgefallen, dass 'vbcc' anscheinend nicht mehr in der Lage ist, ein MUI-Programm fehlerfrei zu übersetzen.

Der Schuldige ist aber nicht 'vbcc', sondern "SDI_compiler.h" (v1.31, 29.03.2009) und "SDI_hook.h" (v1.20, 26.03.2009).
In "SDI_compiler.h" wird zwar das REG-Makro korrekt definiert, komischerweise wird aber im Programm selber das PPC-Makro verwendet, das bedeutet, dass die Argumente in den Register schlummern aber 'vbcc' aus Mangel an Information diese vom Stack zieht und nicht die Register benutzt. Demnach erfolgt u.U. ein Crash wegen illegalen Speicherzugriffes.
In "SDI_hook.h" wird nur auf eine MC68000 CPU für 'vbcc' geprüft, aber nicht die Prozessorfamilie ('vbcc' bietet hierfür __M68K__ an), was dazu führt, dass auch dort die Argumente vom Stack gezogen werden, demnach auch dort ein Crash auftritt (HOOKPROTOxx).

Ich weiß nicht, ob es neuere Versionen gibt. Falls doch, verwendet diese aber testet sie!
Ich selber habe beide Dateien abgeändert, so dass sich diese wie gewohnt verwenden lassen:
Am Ende (aber vor dem letzten #endif) in "SDI_compiler.h" dies einfügen:
c code:
#if  (defined(__VBCC__) && !defined(__PPC__))
#undef REG
#define REG(reg,arg) __reg(#reg) arg
#endif


und diese Zeile in SDI_hook.h von:
c code:
#if defined(_M68000) || defined(__M68000) || defined(__mc68000)


nach:
c code:
#if (defined(__VBCC__) && !defined(__PPC__)) || defined(_M68000) ||
    defined(__M68000) || defined(__mc68000)


ändern.

Das war's.


Wenn jemand aktuellere SDI-Makros hat als ich, möge er sich bitte bei mir melden. Danke.


Grüße
 
jolo   Nutzer

08.05.2010, 15:30 Uhr

[ - Direktlink - ]
Thema: C oder C++?
Brett: Programmierung

@Der_Wanderer:

Zitat:
Ich glaube die "Zufriedenheit" mit der API so wie sie ist kommt daher, dass kaum jemand noch versucht was ernsthaftes damit zu entwickeln.
Den Amiga Proggern geht es wohl eher darum, sich mit dem OS als Selbstzweck zu beschäftigen als mit einer echten, nützlichen Applikation, die entstehen soll.


Würdest Du nur mich ansprechen, würde ich Dir zustimmen. Da ich Programmieren nur als Hobby betreibe, kann daran auch keiner etwa aussetzen. :)
Ich verlange kein Geld für meine Programme, dementsprechend brauche ich auch keine Rücksicht auf Anwender zu nehmen. Ich entwickle hauptsächlich Werkzeuge, die für mich interessant sind.

Ich kann Dir aber auch versichern, dass es professionelle Programmierer gibt, die nach wie vor versuchen ihre zig Mega-Bytes umfassende kommerzielle Anwendung AmigaOS/MorphOS tauglich zu halten, und ich meine diesmal nicht Hollywood.
Zudem sind sie trotz der deiner Meinung nach "Unzulänglichkeiten der Amiga/MorphOS Betriebssystemen" imstande, ihre Programme AmigaOS/MorphOS kompatibel zu halten, teilweise aber mit Abstrichen. Ob es sich für sie rechnet, wird die Zukunft zeigen.


Zitat:
Es werden eher Mini-Projekte gemacht, die zum Experimentieren oder Lernen dienen, aber nicht als richtige Applikation released werden sollen, wo man auf Stabilität, GUI Richtlinien, Integration ins OS, Kompatibilität mit der Aussenwelt etc. wert legt.

Falsch und richtig. Selbst *Mini-Projekte* werden garantiert nicht released, wenn es offensichtliche Fehler gibt.
Bei der GUI gibt es zudem kein falsch und richtig. Die einen benutzen MUI, die anderen Reaction, andere wiederum BOOPSI und die ganz Harten nach wie vor Intuition-Objekte als solche. Es gibt keine einheitliche GUI. Unter MorphOS sollte man MUI verwenden, unter AmigaOS4 Reaction, unter AROS Zune, aber unter OS3? Da bleibt es jedem selber überlassen.
Wenn man halbwegs Übertragbarkeit in Betracht zieht, muss man MUI verwenden, aber mit den Einschränkungen der jeweiligen Form für das zugrunde liegende System leben.

Integration ins OS sowie Kompatibilität mit der Außenwelt sind nur dann wirkliche Herausforderungen, wenn man ganz, ganz tief unten ansetzt beim Programmieren. Die meisten nehmen vorgefertigte Funktionen dafür, siehe Datatypes, und können somit sicherstellen, dass ihre Applikationen sich nahtlos ins System integrieren.


@Thore:
Zitat:
Das Problem ist wohl eher dieses: Man sieht auf Linux ein Programm, versucht es zu portieren. Es ist posix, benutzt vll noch fork/vfork und schon fängt das erste Problem an: Kein posix, kein fork.

Solange es die POSIX-API benutzt kann man es portieren, auch wenn einige POSIX-Funktionen in der entsprechenden Amiga-Implementierung nicht vorhanden sind. Es bedeutet aber einen Mehraufwand, weil man die fehlenden Funktionen nachbilden muss.
Bei fork() sieht es ähnlich aus aber man kann es leider nicht wirklich benutzen, weil es keine Benutzerrechte unter AmigaOS gibt.
Demnach, da hast Du Recht, ist es fast aussichtlos ein Programm zu portieren, dass fork() benutzt.
Für MorphOS/AmigaOS4 bin ich mir nicht sicher, ob es nicht doch möglich ist solch eine Funktion nachzubilden, weil beide versuchen, mehr POSIX-Style (Linux) Programmierung zu erlauben, bzw. die Low-Level-Funktionen die als Basis dafür dienen, anzubieten.
Da müsste man sich an die jeweiligen Entwickler wenden. Ich bin da überfragt. :)


@Der_Wanderer:
Zitat:
Aber ich bin nun immerhin in der Lage, wenn du mir jetzt sagst: "Programmiere ein Tool, wo ich ein Bild reinladen kann, die Schärfe und Farbraum anpassen, resizen und als JPEG, PNG, BMP oder IFF abspeichern."
Dann kann ich das in 2-3h erledigen, und zwar so dass es unter OS3, OS4 und MOS funtkioniert.
Mit der AmigaOS API direkt brauche ich dafür 20-30h, oder vermutlich noch wesentlich mehr wenn man die Saver und DSP Algorithmen noch entwickeln muss, und dannach auch noch Beta Testen auf den verschiedenen Plattformen.


Na, so schlimm ist es nun wieder auch nicht.
In 2004 habe ich innerhalb eines Nachmittages ein solches Beispiel programmiert, allerdings ohne Abspeicherungsmöglichkeit und Skalierung, jedoch mit der Möglichkeit zur freien Rotation unter Verwendung des Bilinear-Patches.
Die Möglichkeit zur Skalierung wurde nachträglich hinzugefügt (Eigenentwicklung, ca. 1 Stunde Aufwand). Der betreffende C-Quellcode des gesamten Beispiels dürfte noch in der entsprechenden Mailingliste (Yahoo) vorhanden sein.


@Holger:
Zitat:
Das mag für C-Programmierer so sein, insbesondere, wenn die IDEs, die sie sich vorher angeschaut haben, tatsächlich nur umständlich zu bedienende makefile-Generatoren waren.
Wenn man erst mal mit anderen Programmiersprachen gearbeitet hat, kommt einem so etwas wie eine Rückkehr zur Steinzeit vor.


Die wirklich erste gute IDE, abgesehen von Devpac 3, die ich verwendet habe, war die, die dem MaxonC++-Compiler spendiert wurde. Ausgeklügelt angelegt, bunt ( :) ), übersichtlich, intuitiv zu bedienen.
Die VC++ IDE unter Windows ist bestimmt nicht schlecht - und trotzdem komme ich mir nicht vor als wäre ich wieder im Steinzeitalter gelandet nur weil ich handverfasste 'makefiles' benutze.
Zudem glaube ich nicht, aber ich kann mich täuschen, dass ein Projekt mittels einer IDE erstellt, so ohne weiteres auf andere Systeme übertragbar ist. Demnach, falls meine Aussage richtig ist, muss man sich ohnehin mit 'makefiles' beschäftigen, wenn man denn etwas von einer anderen Plattform portieren möchte bzw. auf eine andere portieren möchte, jedenfalls für C/C++.

Da die Programmiersprachen, die ich momentan benutze als ausreichend für meine Belange erscheinen, sehe ich auch nicht die Notwendigkeit, eine IDE zu erlernen.
C und C++ sind relativ weit *unten*, Java und Co relativ weit *oben*, demnach denke ich, dass man bei höheren Programmiersprachen mehr Wert auf eine IDE legt, abgesehen vom persönlichen Geschmack.
Es gibt nämlich auch Assembler-Programmierer, die eine IDE verwenden. :)


Zitat:
Mir persönlich bringt eine IDE auf dem Amiga (OS3) aber solange nichts, wie mir schneller als ich schauen kann das Betriebssystem unterm Hintern wegschmiert, und das nur bei kleinen Fehlern.
Zitat:
Ja, woran liegt das wohl...
Da spielt die Kombination aus Programmiersprache und API des Betriebssystems mit Sicherheit eine nicht zu unterschätzende Rolle.



Nee, für Fehler zeichne ich mich alleine verantwortlich. :)
Es gibt Tage, da programmiere ich ohne einen einzigen Fehler im Quellcode zu haben, abgesehen von kleinen Unzulänglichkeiten. Es gibt aber auch Tage, da mache ich dermaßen viele Fehler an einem einzigen Tag, dass ich manchmal an mir selber zweifle. :)


Zitat:
Und Du meinst "Linux" hat mehr Marketing betrieben als QNX?

Ich gehe davon aus. Das Pinguin-Emblem findet man überall, anders als der goldene Stern.


Zitat:
Auch auf einer höheren Ebene bedeutet Programmieren, Zusammenhänge zu verstehen. Man hat allerdings die Gelegenheit, auch größere Zusammenhänge zu verstehen...

Was sind für Dich größere Zusammenhänge?


Zitat:
Natürlich ist es ein Ressourcen/Zeit Problem. Deshalb kann sich Linux auch leisten, grottige APIs anzubieten und irgendwer baut dann schon bessere High-Level APIs drumherum, gerne auch zwei, drei verschiedene Parteien gleichzeitig, so entstehen Gnome und KDE, WebOS und ChromeOS und trotzdem bleiben noch Ressourcen übrig, um darauf aufsetzend auch noch nutzbare Anwendungen zu stricken.

Der Amiga hat solche Ressourcen nicht, und genau deswegen ist es umso wichtiger, die Ressourcen nutzbringend einzusetzen und nicht dafür zu verpulvern, zum hundertsten Mal den gleichen Workaround um eine unzureichende Funktion zu bauen.


Obschon Du definitiv Recht hast, spielt es doch nur eine entscheidende Rolle für kommerzielle Projekte, die mal eben so auf die Schnelle portiert werden sollen. Gut, dem Der_Wanderer schwebt ein kommerzielles Produkt vor, da ist so etwas mehr als ärgerlich, auf der anderen Seite existieren aber (Hobby-) Programmierer, die mit solchen Zuständen auch gut leben können. Zudem sind, wie whose schon ausgeführt hat, die unterschiedlichen APIs seitens MorphOS/AmigaOS4 eine größere Belastung für jeden Programmierer, es sei denn, er legt sich auf ein System fest. Meiner Meinung nach gibt es "der Amiga" nicht mehr. Bis 1993 ja, danach teilte sich ja alles auf. Wir haben mittlereile fünf Systeme (sechs ?). Classic Amiga, PowerUp (?), WarpOS, AROS, MorphOS, AmigaOS4 (in order of appearance, AFAIR). Ich denke, wir können getrost davon sprechen, dass "der Amiga" als solches nicht mehr existiert.


@Der_Wanderer:
Zitat:
Eigentlich müssten sich alle verbleibenden Entwickler erstmal auf eine freie, offene high-level API für AmigaOS stürzen.

Wenn Du mehr als eine Personen in ein Boot steckst und keine klare Hierarchie besteht, wird nur Chaos dabei herauskommen.
Hat aber einer das letzte Wort, muss sichergestellt werden, dass diejenigen, die etwas ausarbeiten sollen, es auch tun, ohne wenn und aber. Üblicherweise spricht man dann von einem Angestelltenverhältnis. :)
Du weißt worauf ich hinaus will?

Habe ein wenig Geduld, irgendwann erfahren wir, ob MorphOS oder AmigaOS4 oder auch AROS das Zeug dazu haben, weiter zu bestehen. Für Dich, der etwas Kommerzielles vertreiben möchte, ist es bestimmt nicht der beste Rat, aber am Beispiel von Hollywood kann man erkennen, dass es jetzt auch schon möglich ist kommerzielle Wege zu beschreiten, allerdings dies mit Aufwand verbunden ist.
Ob Du dazu bereit bist, liegt einzig und alleine bei Dir.
Anbei, eine einheitliche API für die verschiedenen Systeme wird es meiner Meinung nach nie geben.


Grüße
 
jolo   Nutzer

06.05.2010, 22:37 Uhr

[ - Direktlink - ]
Thema: C oder C++?
Brett: Programmierung

Da dieser Thread zu lang geworden ist um auf alle Beiträge einzugehen, ich zudem gestern Skat-Abend hatte, hier nur kurz meine Gedanken.

Fakt ist, und da stimme ich whose uneingeschränkt zu, dass das Amiga Segment in unterschiedliche Lager aufgeteilt ist und die jeweiligen APIs immer weiter auseinanderdriften.
Fakt ist aber auch, dass dies ein natürlicher Prozess ist, der weder aufgehalten werden kann noch soll. Unsere eigene Existenz ist durch solche Abläufe bestimmt worden, ansonsten säßen wir nach wie vor als kleine Gruppe um ein Lagerfeuer herum (falls wir soweit wären, ein Feuer zu entfachen) und würden beten, dass uns bei Nacht nicht irgendein Tier auffrisst. :)
Fakt ist aber auch, und da stimme ich Der_Wanderer zu, dass es abstrakte APIs gibt, die es sehr erleichtern ein Programm auf einem völlig fremden Betriebssystem ohne irgendwelche Änderungen zu kompilieren und auszuführen, ohne dass irgendwelche Fehler auftreten.
Solange aber auf der MorphOS und AmigaOS4 Seite nicht die Version seitens der Kernentwickler bereitgestellt wird, die annähernd dem entspricht was sich diese Entwickler für das jeweilige Betriebssystem wünschen, solange wird kein (Hobby-) Programmierer sich die Mühe machen, eine API zu schreiben bzw. portieren, die losgelöst vom zugrunde liegenden Betriebssystem ist. Den kleinsten gemeinsamen Nenner den wir heutzutage haben, ist die POSIX-API. Damit kann man UNIX, BSD, Linux, QNX, MS-Windows (mit Einschränkungen) und viele andere Betriebssysteme auch, inklusive des AmigaOS (sowie Klone) (mit Einschränkungen) und das MorphOS-Betriebssystem (mit Einschränkungen) programmieren.
Der Nachteil an POSIX ist, dass es C zwingend voraussetz sowie auf spezielle Merkmale eines Betriebssystems nicht eingeht und zum Thema Benutzerschnittstelle nur die Konsole anbietet.

Zum Thema Datatypes kann ich nur anmerken, dass das Konzept veraltet ist, da es nicht die heutigen Belange abdeckt, und zwar das Laden und Speichern von Dateien, die im Netzwerk liegen, inklusive wahlweiser Abbruchmöglichkeit des jeweiligen Vorganges. Ach ja, das leidige Thema Netzwerk und Internet seitens des Amiga/MorphOS Betriebssystem... Hier besteht auch noch Nachholbedarf obwohl sich die Situation schon sehr gebessert hat.

Bezüglich IDE: Viele Programmierer benutzen keine IDE, sondern einen Texteditor nach Wahl und 'makefiles'. Es gibt aber sicherlich genauso viele Programmierer (wenn nicht sogar mehr), die eine IDE benutzen.
Mir persönlich bringt eine IDE auf dem Amiga (OS3) aber solange nichts, wie mir schneller als ich schauen kann das Betriebssystem unterm Hintern wegschmiert, und das nur bei kleinen Fehlern. Das Laden einer IDE unter AmigaOS3 dauert mir viel zu lange, da lobe ich mir schlanke Texteditoren, die es zu Hauf auf dem Amiga gibt.
Komischerweise nutze ich heute unter Windows auch keine IDE obschon MS Studio 2008 komplett vorhanden ist, sondern schreibe lieber 'makefiles' für 'nmake'. Geht sehr wahrscheinlich darauf zurück, dass mir Frank Wille 'makefiles' gemailt hatte, die selbst 'nmake' abdeckten, obwohl er nach eigenen Aussagen mit Windows nichts am Hut hat.
Von Profis kann einer wie ich viel lernen bzw. viel klauen... ;)

Ich habe zudem eine andere Ansicht als Der_Wanderer bezüglich "warum ein Betriebssystem ein Erfolg wird oder nicht".
Der Schlüssel zum Erfolg, meiner Meinung nach, ist das Marketing. IBM OS2 war zu jener Zeit in jeder Hinsicht besser als Windows, es wurde trotzdem kein Erfolg.
Ich behaupte mal, dass QNX Neutrino wesentlich besser als Linux ist - und es trotzdem kein Erfolg wurde.
Das kann man so weiterspinnen.
Ich glaube, wer gut täuscht, hat schon die halbe Miete gewonnen. :)
Nichtsdestotrotz ist jedes Betriebssystem für sich genommen ein Glanzstück an Programmierkunst. Man macht sich keine Gedanken, was die betreffenden Programmierer geleistet haben bzw. leisten, um aus einer Ansammlung von elektronischen Komponenten ein funktionierendes 'es' zu schaffen.
Demnach halte ich es wie whose: Ich bin mit dem zufrieden, was ich vorfinde, auch wenn es bedeutet, sehr viel Zeit in Funktionen zu stecken, die noch nicht im Betriebssystem verankert worden sind bzw. noch von keiner dritten Partei geschrieben wurden (Stichwort: Library).
Und ja, auch Der_Wanderer hat Recht: Je weniger Zeit man sich mit Low-Level-Funktionen rumplagen muss, desto schneller sieht man Ergebnisse. Nur, sind wir davon bei der Amiga/MorphOS-Programmierung weit entfernt. Aber, das macht auch einen Teil des Reizfaktors beim Programmieren aus - die Zusammenhänge zu verstehen und nicht nur etwas nutzen. Alle, die ausschließlich letzteres wollen, sollten einen Blick auf Hollywood werfen.


Grüße
 
jolo   Nutzer

04.05.2010, 23:05 Uhr

[ - Direktlink - ]
Thema: C oder C++?
Brett: Programmierung

@alle und niemanden:

Bevor ich unten auf die getroffenen Aussagen eingehend antworte, schreibe ich vorab etwas Allgemeingültiges.
Ich muss allerdings vorausschicken, dass ich nicht unter Windows 3.x programmiert habe, so dass ich dafür erst einmal entsprechende Literatur im Internet gelesen habe.

1) Unter Windows 3.x wurden üblicherweise nicht die Referenznamen verwendet, sondern die Referenztabellen (import address table (IAT)), was dazu führen konnte, dass bei Änderungen (Updates) der betroffenen DLLs, die IAT des ausführbaren Programmes mit der EAT (export address table) der DLL nicht mehr übereinstimmte, und somit das Starten des betroffenen Programmes einen Blue-Screen verursachen konnte.
2) Mit Windows-NT wurde zwingend die Benutzung der Referenznamen eingeführt um diese Probleme zu umgehen. Man kann aber heute noch die Referenztabellen verwenden (kann man?), diese sollten nach wie vor nominell vorhanden sein; macht nur keiner mehr, wegen der ungeliebten Blue-Screens - denke ich. ;)
3) Eine DLL ist eine stinknormale, ausführbare Datei; demnach müssen Suchvorgänge gestartet werden, um die Referenznamen zu ermitteln. Seht euch mal das Format einer Windows 32/64 Bit Anwendung an, dann versteht ihr mich.
4) Eine DLL wird immer von einem übergeordneten Prozess verwaltet; beim Amiga nur einmal, und zwar beim Laden von einem Medium in den Hauptspeicher und anschließender Initialisierung, bzw. auch noch beim Rausschmiss. Dazwischen hat kein Prozess mehr irgendeine Bedeutung, sondern alles wird von dem Anwenderprogramm erledigt, implementiert aber in der Bibliothek selber, Open(), Close(). Init() wird nur einmal ausgeführt.
5) Eine DLL klont immer ihren nicht-statischen Datenbereich, und zwar für jeden Thread/Prozess, das heißt, beim Öffnen und Schließen ist wesentlich mehr Arbeit seitens einer CPU gefragt als das bloße Hochzählen bzw. Runterzählen einer Variablen (OpenCount) auf Seiten einer Amiga Shared-Bibliothek.
6) Schaut euch mal die gängigsten Probleme mit COM-Objekten an und was Microsoft dagegen getan hat, und dann behauptet nochmal, dass DLLs nur ein einziges Mal im Speicher stehen.


Dass die classic AmigaOS Bibliotheken unter m68k so effizient sind, hat den Grund, wie wir alle wissen, dass sie ausschließlich für m68k gedacht waren. Für andere Prozessoren und andere Programmiersprachen als m68k Assembler ist dieses Format aber alles andere als passend, so weit gebe ich euch Recht. Nur, DLLs und Shared-Objects sind aber auch nicht gerade der Weisheit letzter Schluss, meiner bescheidender Meinung nach.

Effizienz aus Sicht einer CPU bedeutet Aufwand für den Programmierer; Effizienz aus Sicht eines Programmierers bedeutet Aufwand für die CPU. :)


@Holger:

Zitat:
Ähem.
So etwas passiert genau einmal nach dem Laden der Bibliothek, und ähnliches passiert auch beim Amiga, wenn nach dem Laden einer ausführbare Datei Adressen an die tatsächliche Position im Speicher angepasst werden.


Ja, aber nur Punkt "b". Punkt "a" entfällt; sind statisch in einer Amiga-Shared-Library enthalten. Es wird nur die Basisadresse dazu addiert.
Punkt "c" und "d" gibt es nicht (mit einer Einschränkung: der Ladevorgang vom Medium ins RAM).


Zitat:
Deshalb funktionieren DLLs selbst unter Windows 3.1 auf einem 386 mit 14MHz...

Jo, funktionieren tun auch Classic-Bibliotheken in Verbund mit einer 68000 mit nur 7 MHz recht gut, oder nicht? :)
Nee, Spaß beiseite, siehe Punkt 1 oben.


Zitat:
Wenn man bedenkt, dass der identische Library-Initialisierungscode, inkl. der Verwaltung des Zählers für Anzahl benutzender Programme sich in jeder Bibliothek erneut wiederfinden, statt einmal im Betriebssystem, relativiert sich diese Effizienz erheblich.

Da verwechselst Du was. Jede Bibliothek kann einen ganz anderen Initialisierungscode haben; Sprungtabellen können anhand von 32-Bit absoluten Adressen generiert werden (in C macht man das üblicherweise so), für Bibliotheken die ich in Assembler erstellt habe, benutzte ich aber 16-Bit Offsets relativ zur Funktion; zudem kann man im Initialisierungscode reinschreiben was man will, wie will da das Betriebssystem wissen, was es machen soll?
Selbst Open(), Expunge() und Close() sind immer für die betreffende Bibliothek maßgeschneidert.
Das Classic Bibliotheken nicht der Weisheit letzter Schluss sind, weiß ich auch. Nur, ich persönlich finde das Konzept schon ganz passabel. Okay, nicht für PPC und/oder andere Prozessoren, dafür ist es zu maßgeschneidert.
Zudem, wie ich oben schon einmal geschrieben habe, macht das Betriebssystem nichts mehr nachdem die Bibliothek einmal erstellt wurde; eine Bibliothek ist dann nur noch ein Haufen Code der irgendwo im Speicher schlummert und darauf wartet, dass irgendein Anwenderprogramm diesen Haufen Code ausführt. Nix mit Verwaltung seitens des OS. :)


Zitat:
Die Design-Entscheidung, keine symbolischen Namen, sondern eine Tabelle mit 68k-Sprungbefehlen relativ zum Register A6 zu benutzen, die selbst unter der bevorzugten Programmiersprache C ein Fremdkörper ist, muss man akzeptieren. Aber nicht unbedingt glorifizieren.

Ich glorifiziere rein gar nichts. Habe ich nicht gemacht und werde es auch nicht machen. :)
In Zeiten als Assembler noch richtig populär war und CPUs gerade dabei waren in den einstelligen MHz-Bereich vorzudringen, war dieses Konzept aber sehr effizient - und das von beiden Seiten betrachtet, CPU und Assembler-Programmierer. :)


Zitat:
Diese Art des Linkens ist aber auch gar nicht der Grund, warum man Amiga-Libraries nicht so wie Windows oder Unix-Libraries benutzen kann. Der springende Punkt ist hier, dass man nicht die Datensegmente einer Objektdatei automatisch pro Prozess anlegen lassen kann.

Stimmt. :)
Allerdings sollten Amiga Bibliotheken nicht nur thread-safe sein, sondern reentrant, dass heißt dann, dass keine modifizierbaren Daten den Funktionsaufruf überleben. Demnach braucht man auch keinen geklonten Datenbereich.


@Der_Wanderer:
Zitat:
Das Argument mit der Effizienz kann ich auch nicht gelten lassen.
Wie Holger gesagt hat, die Klartext Funktionen müssen nur einmal beim Programm start in Jump Offsets aufgelöst werden. Das ist selbst auf einem A500 ein vertretbarer und kaum spürbarer Aufwand.


Es geht gar nicht um die einmalige Initialsierung. Der ganze Verwaltungsaufwand, der für eine DLL betrieben werden muss, ist doch deutlich höher als beim Konzept einer Amiga-Shared Bibliothek, das fängt beim Einladen an und hört beim Rausschmeißen auf.

Ich verstehe, dass für Dich als Anwendungsprogrammierer Effizienz bedeutet, mit den geringsten Mitteln den höchstmöglichen Nutzen zu erzielen. Das ist mit einer DLL wohl gegeben. Für mich heißt Effizienz aber, dass der Speicher und die CPU geschont werden.
Wir drei (Holger, Du und ich) haben ganz unterschiedliche Gewichtungskriterien. Und daran muss man sich nicht anstoßen.
Wenn Du sagst, für Dich stellt eine DLL eine sehr gute Lösung dar, ist daran nichts auszusetzen. Ich verstehe Deinen Standpunkt. Es ist aber nicht meiner.


Zitat:
Wenn ich das richtig sehe ist der große Unterschied, dass DLLs jedesmal beim öffnen ihren eigenen Kontext erzeugen, während Amiga Shared Libraries nur einmal gestartet werden, und dann von mehreren Prozessen verwendet werden können.

Wir driften immer weiter in Richtung pro und kontra DLL, bzw. pro und kontra Classic Amiga Library ab.

Wenn Du mal Zeit hast, dann besuche die Microsoft Entwickler-Seite und lese Dir mal die Low-Level-API Funktionen durch oder programmiere unter Windows mal ohne vorgefertigte WINAPI, dann verstehst Du auch meinen Standpunkt.

Können wir dem Ganzen ein Ende setzen und sagen, dass Holger und Du nichts gegen Sprungadressenermittlung anhand von Bezeichnern habt, wogegen ich statische Offsets fest verankert im Programm favorisiere?


Frieden? ;)
 
jolo   Nutzer

03.05.2010, 22:23 Uhr

[ - Direktlink - ]
Thema: C oder C++?
Brett: Programmierung

@Der_Wanderer:

Zitat:
Intern verwende ich hier und da Floats, z.b. um ein Hamming Fenster zu berechnen etc.

Verstehe ich aber nicht ganz, in Amiblitz kann ich doch auch Floats in Shared Libs benutzen.


Du kannst sie auch innerhalb einer in C erstellten Bibliothek verwenden, leider aber nicht die Versionen, die in der statischen Compiler (Runtime) Biblitohek zu finden sind, denn, wir näheren uns wieder dem Anfang dieses Threads, unter OS3 sind diese nicht thread-safe und zum Anderen setzen sie Teile des Startup-Codes als gegeben voraus.

Ich bin ein wenig überfragt, wie Amibltiz Fließkommazahlen handhabt und ob mittels Amiblitz erstellte Funktionsbibliotheken wirklich reentrant sind. Unter C jedoch gibt es diverse Referenzen zu Funktionen, die zwar alle dasselbe tun, z.B. dividieren, aber unterschiedliche Bezeichner haben, weil es neben FLOAT und DOUBLE noch die internen Formate der 68881/68882/68040/68060 FPUs gibt, die auch unterstützt werden.
Diese Funktionsnamen sind in den betreffenden Compilern fest verankert, z.B. __muldf3(), __fixsfsi(), __floatsisf(), __divsf3(), um nur einige unter "gcc" zu nennen. Und diese müssen zwingend reentrant für eine Amiga Shared-Library sein, ansonsten musst Du nämlich jede Funktion, die eine dieser Routinen benutzt, solange sperren, bis die betreffende Routine wieder frei zur Verfügung steht. Wohl kaum durchführbar.

So, nachdem ich mir jetzt mal kurz das 'Change.log' zu "clib2" angeschaut habe, gehe ich davon aus, dass alle Funktionen die Du benötigst, darin enthalten sind, auch die Compiler-spezifischen für FLOAT und DOUBLE.

Damit kannst Du schon mal OS3 und OS4 abdecken.
Unter MorphOS ist "libnix" das Äquivalent.
Macht schon mal drei von vier. :)
Ich hoffe, dass unter AROS die zur Verfügung stehenden "Static Libs" thread-safe sind, dann hättest Du nämlich alle vier abgedeckt.


Grüße
 
jolo   Nutzer

02.05.2010, 22:46 Uhr

[ - Direktlink - ]
Thema: C oder C++?
Brett: Programmierung

@Der_Wanderer:

Zitat:
Es geht um Sprachsynthese, wo es gemeinsame Resourcen gibt, z.B. die Lexica und die Stimmen.

Benötigst Du dazu die mathematischen Bibliotheken? - sprich Fließkommazahlen? Dann rennst Du nämlich ins nächste Problem.
Schon Anweisungen wie:
z = i + 1.5;
oder
i = z / 2.0;
benutzten auf dem Amiga Compiler-spezifische Routinen, die ausschließlich in der jeweiligen C-Runtime Bibliothek zu finden sind.

Erschwerend kommt hinzu, aber eher von theoretischer Natur, wenn ich das noch recht in Erinnerung habe, dass man jedwede zu benutzende mathematische Bibliothek von dem Prozess, der sie verwendet, auch öffnen lassen muss, und nicht nur einmal, wie sonst üblich. Der Grund liegt darin begründet, dass eine Ressource (ausschließlich ein Benutzer für die Nutzungsdauer gestattet) anstelle einer Software bzw. einer Software-Hardware-Lösung verwendet werden könnte und diese per Definition ausschließlich von dem Prozess, der sie öffnete, auch geschlossen werden darf.


@whose:

"Winzigweich"?

Habe den Ausdruck noch nicht vernommen. :)


Zitat:
Ja, aber es luppt auch nur deswegen als DLL, weil man bei Winzigweich entsprechend Aufwand mit dem OS getrieben hat. Normalerweise würde das genauso wenig luppen.

Ja, da hast Du Recht.
Allerdings kommt so etwas als zentrale Schnittstelle für ein schlankes, halbwegs effizientes Betriebssystem nicht infrage, weil:
a) zur Laufzeit externe Verweise aufgelöst werden müssen
b) zur Laufzeit die Sprungadressen ermittelt werden müssen
c) die Sprungadressen anhand des Namens ermittelt werden
d) ein zentraler Prozess die Nutzung dieser dynamischen Bibliotheken gewährleisten muss

In Zeiten von C#/Java und zig Giga-Hertz spielt das für Endanwender aber keine Rolle mehr, weil man es nicht wahrnimmt, bzw. die Geschwindigkeit als ausreichend erachtet.
Das gleiche für OS3, selbst mit einer 100 MHz 68060 CPU, würde abschreckend wirken.

Ich gebe zu, dass eine Amiga-Shared Bibliothek um ein vielfaches schwieriger zu erstellen ist als eine '.dll', jedoch ist ihre Verwaltung aus Sicht einer CPU effektiver.
Zudem hat Microsoft den Sprach-Standard von C um "__declspec" erweitert, damit es dem Programmierer leichter gemacht wird, eine '.dll' zu erstellen. So was müsste es für AmigaOS/AROS/MorphOS geben... :)


Zitat:
Ok, manchmal übernehmen die Entwickler des Betriebssystems den Aufwand für Dich und basteln, naja, interessante, Lösungen dazu, aber für AOS 68k fällt das auf alle Fälle flach, da passiert in dieser Richtung wohl eher nichts mehr.

Ganz genau.
Das Problem, dass der Der_Wanderer haben dürfte, sind nicht MorphOS und AmigaOS4, sondern ausschließlich das AmigaOS3.
Unter MorphOS die richtige 'specs'-Datei für "gcc" installieren, gegen "libnix" linken und fertig.
Unter AmigaOS4 ein Shared-Object erstellen, wahlweise mit "gcc" oder "vbcc", fertig.
Nur unter AmigaOS3 sind die Probleme mannigfaltig.
Bezüglich AROS kann ich leider nichts Aussagefähiges beisteuern, weil ich einen m68k gehosteten "gcc" mit i386-AROS Backend verwende, also ein Unikum.


@Der_Wanderer:

Würdest Du nur eine Plattform unterstützen wollen, wäre es sehr viel einfacher. Alle vier zu unterstützen, ist möglich aber mit Aufwand verbunden.


Grüße
 
jolo   Nutzer

01.05.2010, 12:55 Uhr

[ - Direktlink - ]
Thema: C oder C++?
Brett: Programmierung

@Der_Wanderer:

Es hat mich jetzt mal gerade eine Minute gekostet, um herauszufinden, dass "clib2" thread-safe ist, also das ist, wonach Du suchst. Allerdings existiert "clib2" auf Source-Forge nur für AmigaOS3/4 als Release. Wie viel Arbeit es ist diese C-Runtime Bibliothek für MorphOS/AROS anzupassen, weiß ich nicht. Anbei, nach Aussage von Illka Lehtoranta müsste "libnix" unter MorphOS thread-safe sein. Zudem ist "clib2" eine C-Bibliothek und setzt auch wieder einen Startup-Code voraus. Da ich aber irgendwo schon einmal gelesen habe, dass "clib2" innerhalb einer Amiga-Shared-Bibliothek verwendet wurde, musst Du die Dokumentation zu "clib2" lesen, um herauszufinden, welche Bedingungen dafür eingehalten werden müssen.

Werfe nicht gleich die Flinte ins Korn. :)


Zitat:
Das lädt nicht gerade zum Entwickeln für den Amiga ein. Ich verstehe eigentlich gar nicht warum, steckt doch hinter einem fopen() letztendlich ein Open() der dos.library, was re-entrant ist. Irgendwo beim "einpacken" hat da doch jemand Bockmist gebaut.

Ich entwickle meine Programme lieber auf dem Amiga als unter Windows/Linux, weil ich hier hundertprozentig weiß, welche Betriebssystem-Funktionen meine Programme benutzen. Schon die Benutzung der clib- oder der POSIX-API verschleiern, welche Funktionen man tatsächlich verwendet. Beispiel gefällig?

fopen() in Verbindung mit fread() wird je nach Implementierung und des Quellmediums (Floppy-Disk, Hard-Disk etc.) andere Puffer-Größen verwenden. Z.B. wird anhand des Struktureintrages "Bester Datentransfer" ("<sys/stat.h>") ein Puffer verwendet, der irgendwo im Bereich von 512 Bytes bis zu mehreren Kbytes angesiedelt ist, demnach wird fread()/fwrite() nicht exakt die Anzahl der Daten einlesen/schreiben, die Du angibst, sondern dies alles über einen Puffer im RAM bewerkstelligen, der ohne Dein Zutun alloziiert wurde. Erst wenn Du explizit diesen Puffer (Cache) leerst oder fclose() aufrufst oder auch Dein Programm beendest, werden Daten geschrieben. Beim Lesen ist es wiederum anders. Du kannst sagen ich lese Byte für Byte, intern wird aber ein Puffer verwendet, der Dateien blockweise liest, also zum Beispiel 64 Kbytes auf einmal. Liest Du das nächste Byte, wird keine Lesevorgang ausgeführt, sondern nur der Pufferzähler um ein höher gesetzt (fseek()) und Dir das nächste Byte, das sich im RAM (Cache) befindet, retourniert.
Jetzt hast Du auch den Grund, warum das nicht von Anfang an thread-safe programmiert wurde. Es wurden nämlich Variabeln auf Dateiebene angelegt. Erst als man begann, den FILE-Record (FILE-Descriptor) so zu erweitern, dass diese Puffer/Zähler Teile des FILE-Records wurden, ging man den thread-safe Weg (blödes Wort, aber mir fällt nichts Besseres ein, sorry).
Damit bleibt aber noch immer ein Problem bestehen. Beim Beenden eines Programmes müssen noch alle geöffneten Dateien geschlossen werden sowie alle verwendeten Speicherbereiche dem Betriebssystem zurückgegeben werden. Wie macht man das, wenn man alles im FILE-Record platziert hat, der FILE-Record aber nur dem Anwenderprogramm bekannt ist? Lösung, man erstellt eine Liste mit allen FILE-Records ohne Zutun des Anwenderprogrammes, ergo beim Aufruf von fopen()! Und wo bewahrt man den Zeiger auf diese Liste auf Dateiebene auf? Im Startup-Code! Was macht der Startup-Code wenn dessen Exit-Routine aufgerufen wird? Es testet die Liste; ist ein Eintrag nicht null, wird automatisch flcose() ohne Dein Zutun aufgerufen und damit der Pufferinhalt geleert (flush), die Datei geschlossen und die Speicherbereiche dem Betriebssystem als unbelegt zurückgemeldet!

Ja, ich gebe Dir Recht, der Verzicht auf clib- oder POSIX-Funktionen beim Programmieren unter AmigaDOS (speziell 3.x) bedeutet im Umkehrschluss sehr viel mehr Arbeit, macht mich aber unabhängig von irgendwelchen Implementierungen. Zudem spielt Zeit keine Rolle für mich; bin halt ein Hobby-Programmierer.

Auch solltest Du niemals außer Acht lassen, dass man unsichere Teile immer thread-safe gestalten kann, indem man *nur* die Library-Base klont, also negativ- sowie positiv-Offsets (OS3/AROS/MorphOS, OS4 ist ein wenig *anders*), und jedem Endanwender eine eigene Library-Base zuweist. Dementsprechend braucht man nicht Hand an die Funktionen selber zu legen, sondern nur die Sprungtabelle inklusive des Library-Records für jede Instanz zu reproduzieren (kopieren). Ist allerdings nicht der sauberste Stil, weil eine Shared-Bibliothek im Grunde genommen reentrant sein sollte und nicht nur thread-safe.


Als Ergänzung zu whose Worten kann ich Dir nur ans Herz legen, Weaver (amimedic.de) herunter zu laden.
Es ist ein Programm, das Dir anhand von SFD-Dateien die Grundgerüste für Shared-Libraries erzeugt, und zwar für OS3/AROS/MorphOS und OS4.
Alles was Du dazu brauchst ist dann ein Texteditor, einen C-Compiler, Weaver und fd2pragma und Du erstellst für alle vier Plattformen die benötigten Dateien, inklusiver derer für die Endbenutzer. Nach wie vor musst Du aber erst einmal Deine Funktionen so schreiben, dass diese auch mindestens thread-safe sind, besser wäre aber reentrant. Kriegst Du das nicht hin, klone wie oben beschrieben die Library-Base für jedes aufrufende Programm und dann sollte auch einer Amiga-Implementierung nichts im Wege stehen.
Willst Du weiterhin C++ benutzen, bleibt Dir sowieso nichts anderes übrig, es sei denn, Du kannst exakt bestimmen, ob der vom C++-Compiler generierte Code thread-safe ist.

Mein Fazit:
Wenn man denkt es geht nicht mehr, kommt von irgendwo ein Lichtlein her. :)
Oder anders gesagt, ich hoffe, dass Du jetzt nicht mehr ganz so schwarz siehst.


Grüße
 
jolo   Nutzer

30.04.2010, 20:35 Uhr

[ - Direktlink - ]
Thema: C oder C++?
Brett: Programmierung

@Der_Wanderer:

Zitat:
Hm, das wird komplizierter als ich dachte. Soll ich nun doch besser C nehmen?

Das bleibt Dir überlassen. Wenn Du weißt welchen Code der C++-Compiler generiert den Du verwendest, und Du ausschließlich diesen verwendest, kannst Du es mit diesem angehen. Ich persönlich würde mich aber nicht abhängig von einem C++-Compiler machen wollen; zudem ist eine Amiga Shared-Lib ein Low-Level Konstrukt und somit sollte auch C vor C++ Verwendung finden.

Zitat:
Also wenn ich mich zusammenreise, dann komme ich mit

fopen()
fread()
fwrite()
fseek()
ftell()
fclose()
malloc()
free()

aus. Wobei Konsole Output schon hilfreich wäre, also printf().


Vergesse printf() ganz, ganz schnell. Ich weiß nicht warum so viele Programmierer printf() innerhalb einer Shared-Lib verwenden möchten.
1) printf() ist nicht thread-safe; es arbeitet intern mit Puffern und Variablen auf Dateiebene (global).
2) das AmigaDOS erlaubt es nicht, dass Prozesse File-Handles untereinander austauschen; jeder Prozess ist angehalten, die File-Handles per Instanz zu reservieren und wieder freizugeben.
3) printf() setzt zwingend einen Startup-Code voraus; dieser entfällt beim Schreiben einer Amiga-Shared-Lib.
4) printf() ist eine C-Funktion, unter C++ ist das Äquivalent 'cout'. (SCNR :) )

Wenn Du die Ausgaben nur zur Fehlersuche benötigst, verwende kprintf() (OS3, MorphOS, AROS) oder DebugPrintF() (OS4) und starte vorab Sushi oder Sashimi.


Zitat:
Alles andere ist rein algorithmisch und kann re-entrant oder zumindest thread-safe implementiert werden.
Wenn das nicht geht, wird es schwierig.


Es liegt bei Dir - und einzig und alleine bei Dir. Das Amiga Betriebssystem selbst offeriert seine Funktionen auschließlich in der reentranten Form.


Zitat:
Wenn ich für diese Funktionen AmigaOS API nehmen würde, dann sollte es doch eigentlich funktionieren, oder nicht?

Natürlich, sofern Du Abstand zu Funktionen die in der C-Runtime Lib stehen nimmst.


Zitat:
Was hat man denn in der C Runtime "verbrochen", dass es nicht mehr thread-safe ist?
Bei printf() kann ich das noch verstehen, denn da müsste man sich erst den Handle auf den stdout holen. Aber die anderen Sachen sollten doch funktionieren, oder übersehe ich da etwas?


Es gibt keine Bestimmung die da lautet, dass eine C-Runtime Lib thread-safe sein müsste. Die C-Runtime Lib ist eine statische Bibliothek und wird dem Programm einfach hinzu gelinkt. Thread-safe C-Runtime Libs sind Erscheinungen die nur deshalb implementiert wurden, damit man unter UNIX und Konsorten malloc() und free() ohne Gefahr verwenden kann. Da dort die Dateihandhabung auch im Betriebssystem ganz anders gehandhabt wird wie unter AmigaDOS, kann man dort Sachen gefahrlos durchführen, die das AmigaDOS ins Schleudern bringen würden, also Threads für Dateioperationen benutzen. Beim AmigaDOS ist man gezwungen, ausschließlich den Prozess, der die Dateirechte hält, zu benutzen. Man kann keine Dateirechte einfach so auf einen anderen Prozess übertragen.


@Thore:

Zitat:
Es ist stark abhängig von diesen pragmas/clib/inlines und der Link-Libs ob die printf, fopen etc richtig funktionieren.

Innerhalb einer Amiga Shared-Lib kann man auf die standardisierten C-Lib IO-Funktionen nicht zurückgreifen. Dafür müsste man nämlich Teile des Startup-Codes klonen und diesen Teil in die Lib-Init-Funktion platzieren, was aber ein Tabu ist, da diese Funktionen nicht reentrant sind. Solange nur ein Programm diese Lib benutzen würde, liefe alles noch wie am Schnürchen, nur, wenn gleichzeitig ein zweites Programm diese Lib benutzen würde, würde das Betriebssystem sofort abstürzen.

Leider es ist nicht abhängig von "pragmas/clib/inlines", da diese Dateien nur Header-Dateien sind, demnach keinen realen Funktionscode beinhalten sondern nur die Prototypen und Sprungziele. Auch Stub-Funktionen (Glue-Code) würde funktionieren, falls die betreffenden Funktionen dahinter selber reentrant wären. Dies ist aber nicht gewährleistet bei Funktionen der "libnix"- oder "vc"- Runtime Libs, ganz zu schweigen von den "stream" Klassen. Die unkritischen Teile der "vc" Runtime Library sind nach Aussagen von Frank Wille die 32/64 Bit Support Funktionen, die "ctype" und die "string" Support Funktionen. Die Benutzung andere Funktionen innerhalb einer Shared-Lib kann zu Fehlverhalten führen bzw. in einem GURU enden. Und ich behaupte mal, dass das Gleiche auch für "libnix" gilt.


Grüße
 
jolo   Nutzer

29.04.2010, 19:06 Uhr

[ - Direktlink - ]
Thema: C oder C++?
Brett: Programmierung

@Der_Wanderer:

Zitat:
Also, darf ich nun "sprintf" oder "fopen" in einer Shared Lib benutzen oder nicht?
Sieht so aus, als bräuchte ich dafür eine spezielle Runtime Linkerlib.


Nee, eigentlich sind beide Funktionen tabu. Eigentlich deshalb, weil es bestimmt irgendwo Implementierungen geben wird, die dies erlauben. Mir ist aber persönlich nur eine bekannt, die allerdings eine Close-Sourced Version für ein kommerzielles Programm ist. Wird Dir also nicht helfen.

Standard-IO-Funktionen basieren immer auf einen Compiler-spezifischen Startup-Code; da eine Shared-Library keinen Startup-Code enthält, entfallen diese Funktionen. Zudem sind diese Standard-IO-Funktionen nicht reentrant, meist noch nicht mal thread-safe, so dass sie sowieso nicht verwendet werden dürfen.

Bei sprintf() musst Du sehr vorsichtig sein. Es gibt Implementierungen, die malloc() und free() verwenden, wobei diese beiden Funktionen wiederum auf den Startup-Code aufbauen.

Also sind grob gesagt alle Funktionen die beim Beenden des Programmes automatisch Ressourcen zurückgeben, nicht reentrant und dürfen daher nicht in einer Shared-Library Verwendung finden.


Zitat:
Nachtrag:
Unter Windows und Linux scheint das kein Problem zu sein. Haben dort die DLLs/SOs für jede offene Instanz eigene Addressräume, und die Funktionen müssen deshalb nicht thread-safe sein? Oder ist die Amiga Implementation der C-Runtime einfach crappy?


Du vergleichst zwei verschiedene Paar Schuhe.
Unter AmigaDOS sind Prozesse wirklich eigenständig, unter Linux/Windows wirst Du wohl kaum einen echten Prozess initiieren sondern einen Task/Thread starten, der von einem Prozess verwaltet wird. Dementsprechend kann ein Task/Thread auf Ressourcen zugreifen, die der übergeordnete Prozesses bereitstellt. Beim Amiga gibt es keinen übergeordneten Prozess, also ist der Prozess selber zuständig für das Heranschaffen von Informationen. Beim Amiga erledigt dies der Startup-Code. Zudem können DLLs oder Shared Objects auf die gleichen Funktionen, die ein Task/Thread benutzt, zurückgreifen, was beim Amiga (OS3.x) unter Verwendung von Shared-Libs nur mittels Pointer-Akrobatik durchgeführt werden kann und nicht zu empfehlen ist, da dann eine Shared-Lib bestimmte Funktionen seitens des Prozess voraussetzt.
Auch solltest Du nicht außer acht lassen, dass eine Shared-Lib weder ein Prozess, noch ein Amiga-Task ist, sondern nur eine Ansammlung von Routinen darstellt, die von mehreren Prozessen/Amiga-Tasks gleichzeitig benutzt werden können, was beinhaltet, dass diese Funktionen reentrant sein müssen und nicht nur thread-safe.

Anbei, unter AmigaDOS ist C++ ungeeignet zum Erstellen von Shared-Libs.
C++ ist für komplexere, größere Applikationen die bessere Wahl wobei Treiber, und dazu gehört eine Shared-Lib, mittels C erstellt werden sollten, denn dafür ist C entwickelt worden. Noch generiert ein C++-Compiler programmiert in C++ nämlich keinen thread-safe Code. Man kann, wenn man die Compiler Interna kennt, dies auch mittels C++ bewerkstelligen, aber das impliziert, dass man ausschließlich diesen einen C++-Compiler verwendet. Übertragbarkeit auf einen anderen C++-Compiler ist damit hinfällig.


Grüße
 
jolo   Nutzer

09.11.2009, 12:46 Uhr

[ - Direktlink - ]
Thema: Library bauen mit gcc/AmiDevCPP
Brett: Programmierung

@Thore:

Hast Du das Grundgerüst der Bibliothek schon geschrieben oder arbeitest Du noch daran?
Falls Interesse am Grundgerüst besteht, kann ich eine neue Version von 'Weaver' heute Abend hochladen mittels dem Du solche Grundgerüste erstellen kannst. Voraussetzung ist allerdings eine vorhandene SFD-Datei.

Falls Du nur Probleme beim Kompilieren/Linken hast, so ändere die Befehlszeile für 'gcc' ähnlich der unteren Befehlszeile ab:

gcc -s -msmall-code -m68020 -fstrength-reduce -O3 -noixemul -nostdlib -nostartfiles name-library.c -o RAM:name.library

Fließkomma- sowie Standard-C-Lib-Funktionen sind innerhalb einer Bibliothek ein Tabu weil diese Funktionen weder Thread-Safe noch reentrant sind. Bei Bedarf müsstest Du diese selber unter Verwendung der Betriebssystemfunktionen nachbilden.

Anbei, eine Funktion 'main()' gibt es innerhalb einer Bibliothek nicht. Für MorphOS/AmigaOS4 gibt es spezielle Anker, dies liegt aber im ELF-Format begründet.


Grüße
 
jolo   Nutzer

14.08.2009, 15:20 Uhr

[ - Direktlink - ]
Thema: value to dezimal string
Brett: Programmierung

@Holger

Zitat:
Die ursprüngliche Routine habe ich durchaus verstanden. Allerdings werden dort nirgendwo Divisionen eingespart. Divisionen einzusparen wurde erst von Dir vorgeschlagen.

Hier missverstehen wir uns. In der ursprünglichen Version werden Divisionen durch Subtraktionen ersetzt.
Ich gebe zu, dass dies nicht ganz offensichtlich ist. Dennoch, die schon optimierte und ursprüngliche Version sah so aus:

code:
.2	addq.w	#1,d4
	sub.w	d3,d0
	bpl.s	.2
	add.w	d3,d0
	divu.w	#10,d3
	add.w	#$30,d4


und wurde als Ersatz gewählt für:

code:
.2	divu.w	d3,d0	; d3 = 10000, 1000, 100, 10, 1
	move.w	d0,d4	; Wert retten (Quotient)
	clr.w	d0	; Untere 16 Bits löschen (keine Hausnummern)
	swap	d0	; Restwert (Remainder) in untere 16 Bits
	divu.w	#10,d3	; 10000 zu 1000 usw.
	add.w	#$30,d4	; ASCII


Demnach hat der Autor langsame Divisionen vermieden.

"divu Dx,Dx" kostete eine 68000er 126 Taktzyklen, falls ich das noch recht in Erinnerung habe.
Selbst eine 68060 braucht noch deren 22, 68020/68030 46 Taktzyklen und eine 68040 28 Taktzyklen. Alle Angaben ohne Gewähr.
Wie schon mal angesprochen, mein letztes Assembler-Projekt liegt Jahre zurück...
Falls meine Angaben aber annähernd richtig sind, würde selbst eine 68060 den so optimierten Code oft genug schneller ausführen als irgendeinen, der auf Divisionen fußen würde, denn jede Subtraktion kostet eine 68060 gerade einmal einen Taktzyklus, macht summa summarum maximal 10 Taktzyklen pro Durchlauf und nicht 22. Im besten Fall sogar nur einen Taktzyklus.

code:
Timing Beispiel für 68000er Code unter Verwendung einer 68060
CPU:
.2	addq.w	#1,d4	; 1 Taktzyklus
	sub.w	d3,d0	; 1 Taktzyklus
	bpl.s	.2	; 7, 1 oder 0 Taktzyklen
			-----
			Variiert von 2 bis 9 Taktzyklen je Durchgang

Unter Umständen benötigen die 3 Instruktionen pro Durchgang nur
einen einzigen Taktzyklus. Das lassen wir mal außen vor.
					
Nehmen wir an dass die Branch-Vorhersage beim ersten Mal versagt
(7 Taktzyklen), ab dem zweiten Durchlauf klappt (0 Taktzyklen)
und beim letzten Durchlauf einen einzigen Taktzyklus benötigt so
ergibt sich folgender Wert für die ASCII-Ziffer 9:

1.  Durchgang  9
2.  Durchgang  2
3.  Durchgang  2
4.  Durchgang  2
5.  Durchgang  2
6.  Durchgang  2
7.  Durchgang  2
8.  Durchgang  2
9.  Durchgang  2
10. Durchgang  3
              ---
	      28 Taktzyklen

Für die ASCII-Ziffer 0 wird aber nur einen Durchgang benötigt,
also 9 Taktzyklen.

Demnach variieren die Ausführungszeiten stark je nach der Zahl,
die in D0 übergeben wird.
Der schlechteste Fall wäre 99999, d.h. 140 Taktzyklen, der beste
Fall wäre 0 mit 45 Taktzyklen.

Unter Verwendung der Division sieht dies wie folgt für eine
68060 CPU aus:
.2	divu.w	d3,d0	; 22 Taktzyklen
	clr.w	d0	; 1 Taktzyklus
	swap	d0	; 1 Taktzyklus
			-----
			24 Taktzyklen

Demnach sind es immer 120 Taktzyklen, egal welcher Wert in D0
steht.

Anbei, bei Verwendung einer Langwort-Division
divul.l dx,dx:dx  (44 Taktzyklen/68060)
liegt der Vorteil klar auf Seiten der Subtraktionsmethode.


Bei der 680x0 Assembler-Programmierung sollte der Programmierer einen ungefähren Überblick über die verschwendeten (?) Taktzyklen haben, ansonsten kann man sehr schön in 680x0 langsameren Code schreiben als der, der von irgendeinem Compiler generiert wird (hier im Thread wurde schon darauf hingewiesen).

Nachteilig bei einem Multitasking Betriebssystem ist, dass die Abarbeitung des betreffenden Codes zu jederzeit unterbrochen werden kann was uns dann unter Umständen einen Strich durch die sorgsam gemachte Rechnung macht.
Also ist das was ich oben aufgeführt habe nur Theorie die auch bestimmten Annahmen macht, z.B. dass die Branch-Vohersage beim erstenmal versagt (7 Taktzyklen, könnte ja auch gelingen...), ab dem zweiten Durchlauf klappt (0 Taktzyklen) und beim letzten Durchlauf einen Taktzyklus benötigt. Müsste das Kapitel im 68060 User Guide nachschlagen um mich wieder fit zu machen... Hab' dazu allerdings keine Lust.


Zitat:
Die Lösung, die Du gepostet hast, ist durchaus sinnvoll, wenn es darum geht, auf einem 68000, also nicht 68020+, eine 32 Bit Zahl zu formatieren.

Ich denke, dass der jetzt vorhandene Code, welcher die Subtraktionsmethode mittels einer Langwort-Tabelle durchführt, einen guten Kompromiss für alle MC680x0 Prozessoren darstellt. Siehe Taktzyklen-Auflistung oben - falls die von mir genannten Anzahlen an Taktzyklen annähernd stimmen, wovon ich allerdings ausgehe.


Zitat:
Parat haben und jemandem vorkauen, der alle paar Tage mit einer neuen Frage dieser Art kommt, sind zwei verschiedene paar Schuhe.

Ich sehe das Ganze etwas gelassener als Du. Wenn ich keine Lust habe auf Fragen einzugehen, werde ich mir auch nicht die Mühe machen, darauf zu antworten. Zudem ist gerade die Amiga-Programmierung recht schwierig weil es keine ausreichende, geschweige denn deutsche Dokumentation gibt. Für diejenigen, die seit mehr als 20 Jahren hin und wieder für das Amiga-OS programmieren, erscheint alles irgendwie logisch und ineinandergreifend. Für andere, die erst sehr viel später dazu gekommen sind gibt es aber viel zu viele Fragezeichen die auch nicht mittels der bestehenden Dokumentation aufgelöst werden können. Und die Zeiten als man alles selber bis ins kleinste Detail ausprobiert hat, d.h. disassemblieren bis zum Abwinken und dann eigene Test-Codes schreiben, sollten passé sein. Jetzt gibt es das bequeme Internet und Foren in denen man Fragen stellen kann und auch soll.


Zitat:
jolo hat offensichtlich den ursprünglichen geposteten Code mit einem bestimmten Code für die spezielle Anforderung 32 Bit-Zahlen auf 68000 zu formatieren verglichen und ist zu dem (durchaus richtigen) Schluss gekommen, dass ihm nur geringfügige Teile dazu fehlen, und dabei übersehen, dass diese Anforderung weder genannt, noch von dem ursprünglichen Code erfüllt wurde.

Die Fragestellung war ob der betreffende, noch nicht modifizierte Code für Langworte angepasst werden könnte (Zahlen größer 99999).

Zitat:
...auf langwortgröße sollte es schon funtionieren. wer weis wie?

Dies habe ich in Form des 68020(+) leicht geänderten Code-Snippets gepostet und als Anmerkung eine Alternative für 68000er genannt. Demnach ist meinem Erachten nach die Fragestellung befriedigend beantwortet worden.


@AGSzabo

Zitat:
aber jetzt benutze ich wiederum die funktion von jolo! (und habe ihn in meinem readme creditiert)

Das ist zwar ein netter Zug von Dir aber gar nicht nötig weil ich nicht der Autor der von Dir beschriebenen Routine bin.
Zum anderen würde ich persönlich nur Menschen erwähnen, die einen wirklichen Beitrag zu einem Projekt geleistet hätten.
Würde Dein Projekt ohne meine Anmerkungen nicht laufen? Siehst Du. Demnach kannst Du mich getrost aus Deinen Credits löschen.


Grüße
 
jolo   Nutzer

25.07.2009, 20:43 Uhr

[ - Direktlink - ]
Thema: value to dezimal string
Brett: Programmierung

@whose:

Zitat:
Also zuerst mal, ich finde den Thread hier äußerst lehrreich... ich stelle fest, daß ich in der langen Zeit, in der ich auf die "weit größeren Fähigkeiten eines Compilers in Sachen Optimierung" vertraut habe, eine Menge verlernt habe ;)

Das wird vielen so gehen, mir auch. Kniffe die wir früher aus dem Effeff beherrschten, haben wir verlernt, jedenfalls ich für meine Person zum Großteil.

Zum angeblichen Disput.
Es gibt keinen. Ich ignoriere Holgers Beiträge normalerweise.
Zudem geht es nicht darum, wer was besser kann. Schwanzvergleiche sind was für männlich pubertierende Kinder - aus dem Alter sind wir raus. Holger wird viele Dinge in Sachen Programmierung besser können als ich. Das stört mich nicht, noch weckt das meinen Neid. Es wäre auch komisch wenn es anders herum wäre. Ich bin nach wie vor ein Hobby-Programmierer (und noch dazu ziemlich faul) der seine Brötchen mit ganz anderen Sachen verdient. Was mich jedoch an Holgers Beiträgen stört, sind die darin auftauchenden emotionalen Ausbrüche und der Rückgriff auf Strohmann-Argumente. Demnach werde ich weiter versuchen Holgers Beiträge zu ignorieren, egal was Du davon hältst. Sorry whose.


Grüße
 
jolo   Nutzer

25.07.2009, 15:45 Uhr

[ - Direktlink - ]
Thema: value to dezimal string
Brett: Programmierung

@Holger

Zitat:
Oder einfach nur dämlich ausgedrückt, also Du von den Werten "von 1000000000 bis 1" gesprochen hast.

Da muss ich Dir doch glatt Recht geben.
Zu meiner Entschuldigung muss ich aber anführen, dass ich davon ausgegangen bin, dass man versteht was auch schon innerhalb der ursprünglichen Routine geschieht:
Nämlich (damals) langsame Divisionen durch schnellere Subtraktionen zu ersetzen.


Zitat:
Ich bin kein Profi, nur ein Einäugiger unter Blinden.
Zitat:
Nur äußerst eingebildet, würde es offensichtlich besser treffen.


Du kannst mich halten für was Du willst.

Was ich nicht mag, und das betrifft nicht nur programmieren, ist Kritik zu äußern ohne Lösungen aufzuzeigen. Auch etwas als schlecht programmiert zu bezeichnen, wenn man die Vorgehensweise des betreffenden Codes noch nicht richtig verstanden hat, und damit dann anderen ein falsches Bild dessen vermittelt, was als Lösung herangezogen werden kann, halte ich auch nicht für sonderlich hilfreich.

Ich habe zum Nachvollziehen des Quellcode nicht einmal eine Minute gebraucht obwohl ich mein letztes größeres Assembler-Projekt in 1995 geschrieben habe. Aufgefallen ist mir nämlich der Wert 10000; da hätte es auch bei Dir klingeln können. 10000 wurde früher immer zum Subtrahieren von Wort-Werten benutzt und danach durch 10 geteilt, spricht 1000. 1000 durch 10 = 100 - und so fort. Demnach habe ich nur nach Übereinstimmungen gesucht, et voila, ich wusste wie der Code funktioniert.

Ich erwarte von keinem Leser dieses Forums dass er es auch erkennt, aber ich denke dass Kritik nur der äußern darf, der auch Lösungen parat hat. Einfach nur etwas schlecht zu reden geht meiner Meinung nach nicht in Ordnung. Und nur deshalb habe ich mich überhaupt eingeschaltet.


Zitat:
[...] können Dir nicht nur Einäugige helfen.

Aber nicht mehr lange. Werde das Gefühl nicht los, dass ich Grünen Star bekomme...


So, nachdem Du Deine Meinung kund getan hast und ich meine, können wir uns wieder ignorieren?


Grüße

 
jolo   Nutzer

25.07.2009, 12:00 Uhr

[ - Direktlink - ]
Thema: value to dezimal string
Brett: Programmierung

@Holger

Zitat:
Den habe ich ja ganz übersehen. Klasse Vorschlag, Division durch eine Tabelle mit einer Milliarde Einträgen zu "optimieren". Dass es dann auch auf einem 68000 läuft, ist angesichts des Speicherbedarfs von schlappen 4GB natürlich sehr nützlich...

Ich wollte auf Deine Beiträge nie wieder eingehen, jetzt muss ich es doch weil Du hier (gezielt?) Fehlinformationen verbreitest.

code:
ValToDez:
	movem.l	d2-d4/a1-a2,-(a7)
	push	a0		; Pufferstart merken
	moveq	#10-1,d1	; 10 Stellen (wg. dbf -1)
	lea	divtable(pc),a2	; Divisionstabelle
	move.l	(a2)+,d3	; = 1000000000 f. ersten Durchlauf
	moveq	#0,d2		; Flagge für führende Nullen
.lp1	moveq	#-1,d4		; Zähler für Subtraktionen ohne Überlauf
.2	addq.w	#1,d4		; plus 1 = im Bereich von 0 bis 9
	sub.l	d3,d0		; Subtraktion
	bpl.s	.2		; Solange kein Überlauf (bcc.s)
	add.l	d3,d0		; Negativen (Überlauf!) Wert korrigieren
	move.l	(a2)+,d3	; Neuen Wert aus Tabelle, entspricht d3 / 10
	add.w	#$30,d4		; Nach ASCII wandeln
	tst.w	d2		; Schon Ziffern in Puffer abgelegt?
	bne.b	.4		; Falls ja, auch Nullziffer ablegen
	cmp.b	#"0",d4		; Ist es eine Nullziffer?
	beq.b	.5		; Falls ja, führende Null nicht ablegen
	st	d2		; Sonst Flagge setzen
.4	move.b	d4,(a0)+	; Ziffer ablegen
.5	dbf	d1,.lp1		; Anzahl Stellen
	cmp.l	(a7)+,a0	; Pufferadresse = initiale Adresse?
	bne.b	.pop		; Wenn nicht,
	move.b	#"0",(a0)+	; sonst Nullziffer ablegen (d0 war 0)
.pop
	clr.b	(a0)		; String Terminierung (Puffer muss 11
				; Bytes groß sein)
	movem.l	(a7)+,d2-d4/a1-a2
	rts

divtable
	dc.l	1000000000
	dc.l	100000000
	dc.l	10000000
	dc.l	1000000
	dc.l	100000
	dc.l	10000
	dc.l	1000
	dc.l	100
	dc.l	10
	dc.l	1


Es ist echt schwierig so etwas 68000er kompatibel zu machen...
Und ja, ich habe gerade 4 Gigabytes RAM verschwendet...


@AGSzabo

Zitat:
ah, da sind die profis. geht doch! :-)

Ich bin kein Profi, nur ein Einäugiger unter Blinden.


Grüße

 
 
1 -2- 3 4 Ergebnisse der Suche: 110 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 © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.