Sie sind nicht angemeldet.

1

Sonntag, 19. Juli 2020, 18:09

Erste Erfahrungen mit AmigaOS-Programmierung

Ich hatte vor zwei Tagen mit einem kleinen Programm angefangen...
Es macht noch nicht viel, es stellt bis jetzt nur ein Paar "Sterne" auf dem Bildschirm da.
Zunächst war die Frage, wie ich denn Anwendungen kompiliere, und da alle meine A500 nur einen "normalen" 68000 installiert haben, würde das etwas lange dauern. Deshalb kommt für mich nur Cross-Compiling in Frage.
Ein entspechender Compiler war auch nicht schwer zu finden. Ich habe mich für die Amiga-GCC-Toolchain entschieden, da ich sowieso auf Debian/Linux programmiere und dort der gcc nativ läuft. Man kann sich die ganzen Tools einzeln runterladen und kompilieren, aber ich habe mich für eine Variante entschieden, die nur ein Paar Befehle zum Kompilieren und Einrichten braucht.
Diese ist unter https://github.com/bebbo/amiga-gcc zu finden.
Als nächstes brauchte ich einen Emulator, um das Programm schneller (und gemütlicher) laden zu können.
FS-UAE war die einzige richtige Wahl für Debian, den hatte ich auch früher verwendet.
Nun brauchte ich noch ausreichend Dokumentation, die ist hauptsächlich in den Headern der AmigaOS-Bibilotheken vom Compiler und in den Autodocs
(https://wiki.amigaos.net/wiki/Autodocs:Main) zu finden.
Die erste Programmversion sollte nur ein Fenster aufmachen und einen Text darstellen, mehr nicht. Also mit Hilfe der Docs und Informationen aus dem Netz
Programm geschrieben, mit cross-gcc kompiliert, erstmal Guru 4. Fehler korrigiert, immer noch gleicher Guru. Dann nochmal Alles überarbeitet, Compileroptionen für Prozessor angeben, Startupcode manuell verändert, nütze alles Nichts. Ein Guru nach dem Anderen. Dann habe ich die Dateigröße im ADF gesehen: immer noch die gleiche vom ersten Versuch. ADF-Opus abgecheckt, hatte immer die ADF korrekt verändert. Dann wieder Emulator gestartet, der hatte doch nicht etwa tatsächlich die ADF zurückgesetzt! Im Emulatorordner geschaut, Cache-Datei gefunden und gelöscht. Läuft, Text und Fenster sind da.
Und hat nur zwei bis drei Stunden gedauert, Danke Cache-Funktion! X(

Was lernt man daraus: 1. Software kann nützliche aber nervige Funktionen enthalten; 2. Gleich im Emulator einen Ordner als HDD einbinden...
Nun zu Heute:
Ich habe die Funktionen von Intuition und Graphics schnell verstanden, aber mein Programm könnte schneller sein, also so schnell wie ein A500 es schafft.
Das Programm ist aktuell so aufgebaut:
- Lade Intuition und Graphics und zusätzlich noch Timer für eine feste Framerate.
- Öffne Screen mit 5 bits (32 Farben) und setze Farbpalette
- Öffne Fenter im Screen mit maximaler Größe (320x200/LORES), setze Cursor auf eine 0x0 große Bitmap um ihn auszublenden
- Initialisiere Backbuffer zum Zeichnen
- Init. Timer auf 25 TPS

- In einer Endlosschleife:

- Setze RSEED, Zeichne 10 Sterne auf Buffer, mit zufälligen Positionen und Farbe, verschoben auf X und Y um Zeit / 2
- Positionen und Farben sind immer die gleichen (mit offset) da SRAND mit dem gleichen Seed aufgerufen wurde.
- Blitte Backbuffer auf Screen
- Warte auf Timer

Da das Fenster kein CLOSE oder CTRL-C empfangen kann (da in den WFLAGS deaktiviert), läuft die Schleife für immer, aber sollte etwas nicht funktionieren, werden alle Ressourcen freigegeben und das Programm ohne Crash beendet.
Ich werde erstmal daran weiter arbeiten, das Programm effizienter zu machen und ein Paar richtige "Features" einzubauen.
Aber für den Anfang reichts. Vielleicht wird was draus :D

Bilder:
»Sen« hat folgende Bilder angehängt:
  • stern2.gif
  • stern.jpg

Jochen

CEO & Abschnittsbevollmächtigter

Beiträge: 2 445

Registrierungsdatum: 1. Juni 2012

Wohnort: Nahe L

Beruf: Web-, Datenbank- und Kartenheini

  • Nachricht senden

2

Sonntag, 19. Juli 2020, 18:48

Sehr cool!
Ach du testest das gleich per Emu... ja, das geht auch. Hast du einen 1200er oder 600er auch da? Da kannst du ja sehr einfach eine CF über den PCMCIA einbinden und auch per Hotplug rein und raus nehmen, um Daten vom PC rüber zu schaufeln.
Geht auch mit normalen IDE-Controllern, da aber nicht per HotPlug. :)

Sehr schön, dass du auch gleich noch Quellen und Fehlerlösungen offengelegt hast. Klasse! :thumbsup:

Wir wollen mehr sehen ... :thumbup:

CB1JCY

Hausmeister

Beiträge: 1 637

Registrierungsdatum: 23. Juni 2012

Wohnort: Dresden

  • Nachricht senden

3

Sonntag, 19. Juli 2020, 19:01

Bää...wieder Einer, der den Amiga am System vorbei programmiert? ;)
Ich hatte mich auch mal n bissl mit Assembler auf Amiga beschäftigt. Brav (müslifressermäßig) an die Literatur gehalten und als erstes Speicher vom BS angefordert...
Mit C hab ich da aber nichts gemacht. Da werden vieleicht solche Selbstverständlichkeiten in einem Multitaskingsystem nebenbei mit gemacht?
Schreibe bitte weiter über Deine Erfolge und lass uns evl. auch an ein par Codeschnipseln teilhaben.
Emulator: Ich habe dafür Windowsrechner unter den Pfoten. Da ist der WinUAE sehr gut. Mal schnell was berechnen lassen, geht gut.
In der Cloud findest Du auch nützliche Literatur. Das "Amiga intern" kannste Dir da mal ansehen.Weiterhin viel Erfolg dazu.

Gruß CB1JCÝ
Chat im EUIRC (#amiga-dresden.de)

Jochen

CEO & Abschnittsbevollmächtigter

Beiträge: 2 445

Registrierungsdatum: 1. Juni 2012

Wohnort: Nahe L

Beruf: Web-, Datenbank- und Kartenheini

  • Nachricht senden

4

Sonntag, 19. Juli 2020, 19:25

Das ganze Betriebssystem des Amiga ist C programmiert... wer sich mit so Sachen wie Assembler abgibt, wird zwar mit Glück sehr effiziente Sachen machen können, aber nichts nützliches. ;)
Dafür gibt es ja Hochsprachen, damit man sich um das kümmern kann, was man als Ziel hat, und eben nicht beim Urschleim anfängt... :D

Demos sind sicher in Assembler, aber eben auch sehr speziell und legen dann auch ziemlich schnell n Crash hin, wenn die Umgebungsvariablen nicht haarklein genormt passen. Daher laufen viele Demos leider auch nur auf bestimmten Rechnern mit bestimmter Config und schon ein anderes Kickrom kann die Karre umkippen.

Daher, Nützliches programmieren => Hochsprache
Spielerei und wackelige Ergebnisse => Assembler

:thumbup:

CB1JCY

Hausmeister

Beiträge: 1 637

Registrierungsdatum: 23. Juni 2012

Wohnort: Dresden

  • Nachricht senden

5

Sonntag, 19. Juli 2020, 20:16

Warum Demos wohl in Assembler gemacht sind? Sehr viele Demos sind systemkonform geschrieben, allerdings oft nir auf bestimmten Prozessoren/Kickstarts lauffähig. Da ist C= nicht unschuldig wenn Einsprungadressen und -Bedingeungen verändert wurden.

Warum bei mir Assemblerversuche (mehr wars beim Amiga nicht)?
Weil ich in den 80igern meinen Plus4 auch in Assembler programmiert hatte. Der TED-Mon lud ja gerdezu ein.
Ich will aber hier keine Diskussion über Programmiersprachen losbrechen. Jede hat ihre Vor-und Nachteile.

@Jochen: Immer diese Mähr, dass das Amige-BS in C programmiert worden sei. Lies mal nach:
https://de.wikipedia.org/wiki/AmigaOS
:P

Zitat

Spielerei und wackelige Ergebnisse => Assembler
Du bist ein Kind der 80iger- und hast programmieren in den 90igern gelernt. Daher verstehe ich diese Meinung, akzeptiere Diese aber nicht so. Es gab Zeiten, da wurden Programme noch binär gesetzt. Assembler war ab den 70igern schon ein Fortschritt. Hier, in einem Retroforum, sollte man den einfacheren Programmiertools Respekt zollen. Sooo wacklig waren meine mit TEDMon geschriebenen Sachen auf dem Plussi nun auch nicht. Sie waren nur nicht so umfangreich, erfüllten aber, soweit ich testen konnte, fehlerfrei, ihren Zweck. (Es gibt keine fehlerfreien Programme.)
Übrigens: Als ich mit Delphi programmiert hatte, war ich erstaunt, was im Compilat alles sinnlos mitgeschleppt wurde.
Chat im EUIRC (#amiga-dresden.de)

6

Montag, 20. Juli 2020, 02:19

Soo für Heute Schluss (bissel spät geworden)

Habe noch nen ollen Würfel gezaubert, mit krassen 2 FPS!
(Vielleicht lieber eine andere Methode zum Rendern)
Naja, werde mir Morgen auch mal m68k-Assembler ansehen (wenn ichs verstehe, aber bestimmt).
»Sen« hat folgendes Bild angehängt:
  • wuefel.gif

Jochen

CEO & Abschnittsbevollmächtigter

Beiträge: 2 445

Registrierungsdatum: 1. Juni 2012

Wohnort: Nahe L

Beruf: Web-, Datenbank- und Kartenheini

  • Nachricht senden

7

Montag, 20. Juli 2020, 07:00

Hmm, kann da nix lesen, wie das programmiert wurde!?

Naja, mag für kleine Programme damals gereicht haben, aber bei Assembler fängste ja bei jeder Operation im Urschleim an und ich möchte mir gar nicht vorstellen, was so ein drehender Würfel für einen Aufwand dargestellt hätte.
Wers mag, solls machen, aber nicht die moderneren Sprachen bashen, denn die gibts nicht umsonst denn auch diese basieren natürlich auf Assembler, aber man schreibt sich nicht jedes mal den Urschleim neu, sondern verwendet quasi fertige Codeschnipsel, die da eben Befehle darstelle und diese werden beim compilieren dann ja auch wieder optimiert und auf Maschinensprache zurückgeführt. ;)

Wie gesagt, wer will kann gern Assembler machen, aber nicht jeder ist so masochistisch veranlagt... :D

8

Montag, 20. Juli 2020, 10:25

Benötigt war nur eine Vektor-Mathe-Bibilothek, daraus die Funktionen, sind nur 2 Dateien mehr zu kompilieren.
In den globalen Variablen ist ein konstantes DOUBLE-Array mit Würfel-Eckpunkten hinterlegt. (12[Linien]*2[Punkte]*3[Koordinaten])

Im Render-Struct:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
	mfloat_t position[VEC3_SIZE]; // Kameraposition
	mfloat_t target[VEC3_SIZE]; // Kameraziel
	mfloat_t up[VEC3_SIZE];  // Kamera-Up(gibt an an welcher Achse es hoch geht)
	mfloat_t view[MAT4_SIZE];  // Kameramatrix für die Sichtrichtung
	mfloat_t perspective[MAT4_SIZE];  // Kameramatrix für die Perspektive
	mfloat_t rotation[MAT4_SIZE]; // Matrix für Rotation des Würfels
	mfloat_t raxis[VEC3_SIZE]; // Rotationsachse
	mfloat_t scale[MAT4_SIZE]; // Matrix zum verkleinern des Würfels
	mfloat_t scalar[VEC3_SIZE]; // Skalierfaktor
	mfloat_t transform[MAT4_SIZE]; // Transformationsmatrix aus Sicht und Perspektive
	mfloat_t model[MAT4_SIZE]; // Modellmatrix aus Rotation und Skalierung
	mfloat_t total[MAT4_SIZE]; // Hauptmatrix aus Transformation und Modell
	mfloat_t vertexA[VEC4_SIZE]; // Erster Vertex der Linie
	mfloat_t vertexB[VEC4_SIZE]; // Zweiter

Im Render-Init (1x berechnet):

Quellcode

1
2
3
4
5
6
7
mat4_look_at(rd->view,vec3(rd->position, 0.0, 0.0, -10.0),vec3(rd->target, 0.0, 0.0, 0.0),vec3(rd->up, 0.0, 1.0, 0.0)); // Berechnung der Sichtmatrix
		mat4_perspective(rd->perspective, to_radians(70.0), 320.0/200.0, 0.1, 20.0); // Perspektive
		mat4_identity(rd->scale); // Skalierung auf 1
		mat4_scaling(rd->scale,rd->scale,vec3(rd->scalar,0.25,0.25,0.25)); // Skalierungsmatrix
		mat4_identity(rd->rotation); // Rotation auf 1
		mat4_rotation_axis(rd->rotation,vec3(rd->raxis,0.5,0.1,0.2),to_radians(0.0)); // Rotationsmatrix
		mat4_multiply(rd->transform, rd->perspective, rd->view); // Transformationsmatrix == Sicht * Perspektive

Im Render-Loop:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
SetRast(renderTarget,BLACK); // Bildschirm schwarz

		mat4_identity(rd->rotation); // Rotation auf 1
		mat4_rotation_axis(rd->rotation,vec3(rd->raxis,0.5,0.1,0.2),to_radians(currentStep * 360.0)); // Rotation entlang der Achse um SEKUNDEN/16*360
    	// currentStep sind die vergangenen Sekunden seit dem letzten Rendervorgang (höchstens 1.0)
		mat4_multiply(rd->model, rd->scale, rd->rotation); // Modell = Skalierung * Rotation
		mat4_multiply(rd->total, rd->transform, rd->model); // Haupt = Transformation * Modell

		SetAPen(renderTarget,WHITE); // Weiss zeichnen
		for(int i = 0;i < CUBE_LINES;i++) { // 12 Linien rendern
			for(int d = 0;d < 3;d++) { // Kopieren der Punkte in die Vertexe
				rd->vertexA[d] = cubePoints[i*6+d];
				rd->vertexB[d] = cubePoints[i*6+d+3];
			}
			rd->vertexA[3] = 1.0; // W muss 1 sein
			rd->vertexB[3] = 1.0;

			vec4_multiply_mat4(rd->vertexA,rd->vertexA,rd->total); // Multiplikation Matrix mit Punkten -> neue Koordinaten
			vec4_multiply_mat4(rd->vertexB,rd->vertexB,rd->total);
			

			WORD xA = ((WORD)(((rd->vertexA[0] + 1.0) / 2.0) * 320.0)); // Koordinaten -1.0...1.0 -> Pixelkoordinaten (Y umgedreht)
			WORD yA = ((WORD)(((rd->vertexA[1] + 1.0) / 2.0) * 200.0));
			WORD xB = ((WORD)(((rd->vertexB[0] + 1.0) / 2.0) * 320.0));
			WORD yB = ((WORD)(((rd->vertexB[1] + 1.0) / 2.0) * 200.0));
			if(rd->vertexA[2] < 0.0 || rd->vertexB[2] < 0.0) { // Baufaellig: Prüfen ob Koordinaten (oben Z, unten X und Y) im Bereich liegen (noch nicht benötigt)
				continue;
			}
			if((xA >= 320 || xB >= 320) || (yA >= 200 || yB >= 200) || (xA < 0 || xB < 0) || (yA < 0 || yB < 0)) {
				continue;
			}
			Move(renderTarget,(LONG)xA,(LONG)yA); // Gehe zu Punkt A
			Draw(renderTarget,(LONG)xB,(LONG)yB); // Zeichne bis Punkt B
		}

Naja, OpenGL ist da besser, da es die GraKa nutzt, aber der A500 hat keine, und auch keine FPU, so sind die Fließkommazahlen lahm.
PS: läuft mit diesem Code jetzt 2 FPS schneller :D (vorher Alles im Loop berechnet)!

Jochen

CEO & Abschnittsbevollmächtigter

Beiträge: 2 445

Registrierungsdatum: 1. Juni 2012

Wohnort: Nahe L

Beruf: Web-, Datenbank- und Kartenheini

  • Nachricht senden

9

Montag, 20. Juli 2020, 13:02

Naja, die CustomChips im Amiga haben, soweit ich weiß, spezielle Recheneinheiten für sowas. Ansonsten hätte man die 3D Spiele auf dem Amiga nie so hin bekommen, wenn alles der 68000er hätte rechnen sollen. Aber dafür braucht man sicher spezielle Bibliotheken ...

10

Montag, 20. Juli 2020, 15:08

Aber dafür braucht man sicher spezielle Bibliotheken ...

Eigentlich nicht, graphics.library hat ein Paar Funktionen für den Blitter und Copper und Sprites, diese sollten ausreichen, um das Programm schneller zu machen, und sogar die Flächen zu füllen. Aber: In der technischen Dokumentation habe ich über die Register gelesen, die man mit Assembler erreichen könnte, die man mit der 1.3er Graphics-Lib und auch späteren nicht oder nur indirekt (mit mehr Operationen) ansteuern kann. Die Funktionen nehmen einem Vieles ab, aber es scheint so, dass die Lib wirklich nur für kleinere, "normale" Anwendungen ausreicht (also z.B. für die WB und Anwendungen dafür, keine Spiele/Demos). Man hat zwar Zugriff auf die Koprozessoren, aber man kann sich zum Beispiel den Draw-Modus des Blitters nicht aussuchen, der wird automatisch gesetzt (und noch mehr). Wenn du jetzt nämlich so eine Funktion aufrufst, machen viele davon mehr als benötigt, und schlucken Zeit vom Koprozessor und 68k. Und ich vermute mal, da die meisten Demos auf 500ern laufen sollen, dass die Effizienz eine Große Rolle spielt, da viele Leute einen 500er hatten und nicht mehr.
Ich könnte jetzt trotzdem diese Funktionen verwenden, aber ich werde wirklich erstmal etwas weiter ASM lernen und mich auch mal mit den Koprozessoren weiter auseinandersetzen. Ausserdem: Ich kann C und ASM auch in eine Datei stecken, mit

Quellcode

1
asm("move ...");
. Ich kann dort quasi auch zu(r Adresse) einer C-Funktion springen, mit jmp _FUNKTION, muss natürlich die Funktionsparameter vorher auch richtig setzen, usw. usw. (lerne noch dazu).
Also:
Allgemeine Berechnungen (m68k) ==> C-Funktion
Alles mit Grafik und Zugriff auf irgendwas Anderes ==> ASM-Routine
So sollte ichs hinkriegen.
Aber erstmal werde ich an meinen Projekten am anderen PC weitermachen, Dateiformate, Bildverarbeitung usw. (aber nur in C, x86 hat mir zu viele Instruktionen zum lernen :D ).
Oder ich krame meine OpenGL-Demo wieder raus (mit 300+ FPS!)...

Jochen

CEO & Abschnittsbevollmächtigter

Beiträge: 2 445

Registrierungsdatum: 1. Juni 2012

Wohnort: Nahe L

Beruf: Web-, Datenbank- und Kartenheini

  • Nachricht senden

11

Montag, 20. Juli 2020, 17:55

Ja, in ASM kommst da natürlich an alles ran, aber davon bekomm ich Kopfaua... lol

Demos haben die auch unbedingt in ASM geschrieben, denn die haben meist alles aus der HW geholt, und getrickst, was nur ging. :D
Mit ner 0815 C Bibliothek biste da natürlich n Loser. :D Aber fürs meiste reicht das und man kann sich mehr auf die Aufgabe konzentrieren, wenns nichts extrem super hochperformantes werden muss. :thumbup:

Sag mal, kann ich den Thread nach Software verschieben, oder soll der unbedingt geschützt bleiben?

12

Montag, 20. Juli 2020, 18:08

Sag mal, kann ich den Thread nach Software verschieben, oder soll der unbedingt geschützt bleiben?

Kannst du ruhig verschieben.
Werde Morgen mal anfangen, diesen (grauenhaften) Renderer versuchen gegen die Blit-Funktionen (Oder einfach 2D-Sprites fürs Erste) zu ersetzen, bin sowas halt von opengl gewöhnt, aber der Amiga tickt da halt ganz anders.
Ich habe übrigens den Renderer noch langsamer gemacht, da ich noch einen Tiefentest und "richtigen" Linienrenderer hinzugefügt hab, aber das kommt eh in den Papierkorb, da für den Amiga nicht geeignet (aber läuft immerhin).