"Kompilierung" von Grafik zu Assembler-Code, für maximale Geschwindigkeit?

Diskussion zum Thema Programmierung unter DOS (Intel x86)
DOSferatu
DOS-Übermensch
Beiträge: 1220
Registriert: Di 25. Sep 2007, 12:05
Kontaktdaten:

Re: "Kompilierung" von Grafik zu Assembler-Code, für maximale Geschwindigkeit?

Beitrag von DOSferatu »

@zatzen:
Ja, innerhalb der ISR vom Ticker sollte man nicht allzuviel machen.
Den Ticker benutze ich auch nur so: Ich erhöhe irgendwelche Zähler, setze Flags, o.ä. - Die eigentlichen Dinge werden dann in der Hauptschleife ausgeführt - die prüfen, ob ein Flag gesetzt, ein Zähler einen Wert über-/unterlaufen hat usw. - D.h. den Ticker nutze ich dann mehr dazu, daß nicht eine Funktion vor der anderen "davonläuft".

Man kann natürlich auch einige einfache Dinge innerhalb des Tickers machen - beispielsweise fülle ich im Ticker den "Steuerpuffer" für Figuren - damit ich genau so viele Steuerbefehle (gedrückte Tasten-/Kombis) kriege wie ich Steuerschritte in der Figuren-/Spiel-Steuerung habe. Und natürlich, wenn ich DIgi-Sound über PC-Speaker abspiele, da ist das ohne Ticker quasi nicht möglich (außer wenn man außer Soundabspielen nichts weiter machen will).

Und wegen Unterstützung: Windows XP (32bit) unterstützt auch den Sound-Blaster.
Wie schonmal erwähnt: In C:\WINDOWS\System32\autoexec.nt einfach sowas schreiben wie:
SET BLASTER=A220 I5 D1 T2
oder ähnliches - je nachdem, was man haben will. Und der supportet dann die entsprechende SB, d.h. er erkennt die Portzugriffe und spielt es dann auf der Soundhardware/Soundtreiber ab, der installiert ist. D.h. die NTVDM (das ist das Ding in 32bit-Windows, das die 16bit-Programme ("DOS", Realmode) ausführt) tut dann so, als wäre die Soundkarte im System, die dem BLASTER Wert entspricht. - Funktioniert bei mir seit Jahren tadellos.

Ich hab's noch nicht mit AdLib probiert - aber eine SB enthält ja auch die Funktionalität der AdLib-Karten. Könnte also sein, daß auch das ganze AdLib-Zeug dann mit funktioniert.

(Auch das ganze Ticker-Zeug funktioniert übrigens unter Windows - außer wenn man die Tickerfrequenz über 1000 Hz stellt.)

Windows XP war nicht umsonst so beliebt und wurde viel länger supportet als vorgesehen:
Das beste aus allen Welten: Die Forschrittlichkeit der NT-Linie, die Einfachheit der Win9x Linie, die Abwärtskompatibilität zu alten 16bit-Windows und zu DOS. Wenn DOS-Programme unter WinXP laufen, Zugriff auf INTs, die dann lange FIlenamen ermöglichen (lesend/schreibend). DIe Zwischenablage von Windows kann man von DOS aus nutzen (Bei Win9x einfach so, für WinXP hat einer n Treiber gebaut, seitdem kann ich das auch direkt zwischen DOS und Windows benutzen.)

Schon wieder zu viel Text meinerseits. Und ja, ich weiß: Du magst die ganze alte DOS-Hardware: VGA, AdLib, SoundBlaster, Keyboard - aber aus irgendwelchen Gründen den Timer nicht. Ich wollt auch nicht damit nerven, nur 'n paar vielleicht nützliche Informationen streuen.
wobo
DOS-Guru
Beiträge: 614
Registriert: So 17. Okt 2010, 14:40

OPL2 vs. OPL3 Re: "Kompilierung" von Grafik zu Assembler-Code, für maximale Geschwindigkeit?

Beitrag von wobo »

OPL3 braucht nur 0,28 Mikrosekunden Wartezeit nach einem Schreibzugriff, das ist alles.
Vielleicht ist OPL3 Hardware aber auch als AdLib konfiguriert entsprechend schnell, so dass ich das per Konfiguration einstellen würde, wie lang gewartet werden muss.
Ja. Zumindest, was man so immer wieder lesen kann, z.B. hier
http://www.fit.vutbr.cz/~arnost/opl/opl3.html

OPL3 braucht eben viel weniger Wartezyklen als OPL2, egal in welchem Mode der OPL3 betrieben wird. Du kannst also einen klassischen 9-Stimmen-OPL2-Player schreiben, und bei Vorhandensein eines OPL3 dann die schnelleren Ausgaberoutinen für den OPL3 verwenden.

Du bist bei den erweiterten Modi des OPL3 (siehe Link oben) auch nicht gezwungen, diese in Stereo zu verwenden. Beim OPL3 kannst du für jeden Kanal einstellen, ob er links, rechts oder zentriert ist. Du könntest also auch einen 18-Stimmen-OPL2-Track in Mono abspielen.

Ein OPL3-Stück, das den 4-Operatoren-Mode benutzt habe ich übrigens hier gefunden
https://www.youtube.com/watch?v=01TXqmPN520

Du musst also jetzt nicht extra für mich noch einen OPL3-Tracker mit 4-Operatoren-Mode schreiben :-)

Einen Disclaimer noch: Ich habe nie selbst etwas für den OPL3 programmiert, sondern das nur vorgehabt und mit deswegen durch ein paar Doks gewühlt (ist allerdings schon Jahre her). Ich kann also nicht wirklich helfen, und nur auf die Links verweisen!

Übrigens, vielleicht was für die Admins:
Während ich hier schrieb, schrieb auch DOSferatu was, und als ich meine Nachricht abgesendet hatte war sie einfach weg.
Das ist leider schon seit meiner Anmeldung vor 10 Jahren so. Ist mir auch oft passiert, wenn ich mit einer Antwort zu lange gebraucht habe, weil ich zu lange an ihr herumgefeilt habe.

Wenn ich nicht wirklich ganz schnell eine q&d-reply hier im Forum mache, erstelle ich die Antworten immer extern mit einem Texteditor und copy&paste dann.
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: "Kompilierung" von Grafik zu Assembler-Code, für maximale Geschwindigkeit?

Beitrag von zatzen »

@DOSferatu:
Ist doch gut, ich hab es gerne gelesen!

Den Ticker benutze ich auch aktuell deshalb nicht, weil ich die Sache zuletzt schlichtweg nicht zum Laufen gebracht habe (Absturz) und erstmal keine Nerven hatte das hinzukriegen. Deshalb ja: Evtl. später.

Die andere Seite mit dem Ticker-Problem, bezieht sich auf die Sache mit der variablen Framerate. Diese möchte ich lieber, wenn möglich, "monolithisch konstant" halten, da sich dann sehr vieles einfacher gestaltet. Man verschenkt dabei natürlich potentielle Performance, hier würde ich dann aber erstmal damit leben können, dass etwa ein Spiel einen 486-100 braucht was sonst auch, allerdings öfters "ruckelnd", auf einem 486-25 laufen würde.
Vielleicht fällt es mir aber leichter, wenn ich eine variable Framerate ersteinmal in einer technischen Umgebung zu realisieren versuche, die keinen digitalen Audiopuffer "im Hintergrund" erzeugen muss. Sondern eben AdLib und One-Shot-DMA Einzelsounds. Das könnte mir das Brett vorm Kopf in der Angelegenheit nehmen. Ich habe das "Problem", dass ich alles immer wirklich verstehen und mir selber autodidaktisch erarbeiten muss. Ich denke, das wäre hier für mich ersteinmal der richtige Weg.

Mein Lieblings-"Feature" von DOS ist VGA bzgl. vielmehr MCGA.
Einfach Daten in die Adresse - zack, Grafik auf dem Bildschirm.
Ich programmiere unregelmäßig aber gerne, und ich lerne langsam und stetig dazu. Aber ich versuche nicht, zielstrebig ein "Profi" zu werden, etwa um, wie es vor 30 Jahren vielleicht sinnvoll gewesen wäre, bahnbrechende Software rauszubringen, d.h. von der technischen Seite her, die Hardware maximal auszreizen.
Daher ist für mich der echte VGA Modus und dessen Programmierung nach wie vor ersteinmal ein Buch mit sieben Siegeln.

MCGA scheint zudem irgendwie ein Standard gewesen zu sein, sehr viele Spiele, gerade auch die "ganz großen", nutzten diesen Modus wenn ich das nicht falsch beobachtet habe.

Also... Solange ich hier etwas 100% alleine mache, erwarte ich von mir auch gar nicht, dass es etwas weltbewegendes wird. Für sowas bräuchte man eben ein Team, wo sich jeder mit seinen Stärken einbringen kann.
Dass sowas im Hobby-Bereich meist nicht funktioniert weil irgendwer irgendwann einfach keinen Bock mehr hat und dann aussteigt, davon hattest Du erzählt, und das ist nachvollziehbar.
mov ax, 13h
int 10h

while vorne_frei do vor;
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: "Kompilierung" von Grafik zu Assembler-Code, für maximale Geschwindigkeit?

Beitrag von zatzen »

@wobo:

Das ist doch eine tolle Sache, dass ein OPL3 auch für OPL2 nur 0.28 µs Wartezeit braucht.
Vielleicht, bzw. wahrscheinlich, kann man eine OPL3 Karte sogar automatisch erkennen.
Eine AdLib lässt sich auch erkennen, das wusste ich bisher nicht - weil man ja einfach in 388h und 389h "reinballern" kann, ohne dass es schadet, wenn keine AdLib installiert ist.

OPL3 Stereo: Nach meiner Erfahrung kann man einstellen, ob links, rechts oder auf beiden Seiten. Das ist "tontechnisch" ein wenig anders als eine richtige links-rechts-Verteilung, weil nur links oder nur rechts effektiv 6 dB leiser ist als "beide Seiten". Man kann so arbeiten, aber es wirkt immer ein wenig so, als wenn was kaputt ist, wenn man einen Klang nur einseitig benutzt.

18 Stimmen... Also, das kann sinnvoll sein, je nachdem mit welcher musikalischen Philosophie man da rangeht, mein Tracker soll neben der "komischen" Instrumentendefinition aber auch relativ einfach und übersichtlich für Anfänger werden.
Vielleicht bekomme ich 9 Kanäle gleichzeitig im Textmodus 80x50 nebeneinander dargestellt.
Ich kann hier ja noch ein bisschen ausholen:
Es ist ohne weiteres möglich, mit dem klassischen Amiga-MOD Format, mit 4 Kanälen, tolle Musik zu machen. Dabei hat Sample-Musik allerdings ein Ass im Ärmel: Samples können auch direkt ganze Akkorde, 3- oder 4-Klänge sein.
Bei AdLib hat man das so nicht, braucht also für adäquate Möglichkeiten 3 Kanäle + weitere 3-4 Kanäle für Akkorde. Das ist aber so klein Problem, denn das sind ja nur 6-7 benötigte Kanäle, da ist man mit 9 Kanälen gegenüber MOD sogar noch besser dran.
Noch krasser wird das "genug Kanäle haben", wenn man mit dem C64 oder Nintendo NES vergleicht. Der SID hat nur 3 Kanäle, NES vielleicht vier, wenn man Noise und PCM rauslässt, wobei letzteres kaum benutzt wird.

Ürbigens kann man AdLib ja auch auf 6 Kanäle + Drums schalten. Letztere klingen zwar irgendwie "billig", aber irgendwie doch manchmal gerade deshalb ganz nett. Ich denke, ich werde diese Option im Tracker ermöglichen.

4-Operatoren-Mode: Ja, die Klänge klingen irgendwie frischer, für mich aber immer noch typisch nach FM. Ich werd einfach mal sehen ob ich ungewöhnliche Sounds aus der AdLib rauskriege. Und wenn nicht: Dann hab ich eben einen eigenen AdLib-Tracker, den ich selber wenigstens perfekt bedienen kann, und es wäre mein erster, der auf einem Kanal jederzeit die Instrumente wechseln kann, und Effekte wie Portamento oder Arpeggio hat.

Auch wenn Du selber nichts für OPL3 programmiert hast: Du hast schon sehr geholfen mit dem Fakt, dass eine OPL3 Hardware kaum Waitstate braucht!
mov ax, 13h
int 10h

while vorne_frei do vor;
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: "Kompilierung" von Grafik zu Assembler-Code, für maximale Geschwindigkeit?

Beitrag von zatzen »

Kleines Update:

Ich habe eine Ansteuerung über 0388h und 0389h mit nur einmal 0388h lesen nach Zugriff auf 0389h versucht - es ist fehlerhaft, zumindest in DosBox. Daher muss ich bei 6x bzw. 36x 0388h lesen bleiben.
Dadurch ergeben sich nun rund 33000 mögliche Registerzugriffe pro Sekunde. Das klingt erstmal viel, ob sich das mit meinem Vorhaben verträgt, bleibt abzuwarten.
Ich möchte ja, je nach Geschwindigkeitseinstellung, 50x pro Sekunde etwas an den Operatoren verändern. Im Extremfall könnten das geschätzt um die 200 Zugriffe, x 9 = 1800 Zugriffe sein - das könnte knapp werden, da diese Zugriffe vielmehr innerhalb von nur ein paar Millisekunden stattfinden müssen, da bei 50 Hz ja insgesamt nur ein Spielraum von 20 ms gegeben ist.

Also, schneller Zugriff über die Ports 038xh funktioniert schonmal nicht. In meiner DosBox ist BLASTER auf T6, also SB16 konfiguriert, demnach sollte OPL3 also vorhanden sein, und das wurde über die inoffizielle Erkennungmethode auch erkannt.
Ich denke ich werde es mal über die Ports 220h - 223h probieren - da bestehen für mich allerdings noch Unklarheiten.
mov ax, 13h
int 10h

while vorne_frei do vor;
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: "Kompilierung" von Grafik zu Assembler-Code, für maximale Geschwindigkeit?

Beitrag von zatzen »

So, komisch, diesmal hat es geklappt über Ports 388/89h, quasi ohne Wartezyklen, vielleicht war mir noch ein Fehler unterlaufen. Jedenfalls habe ich auch Zugriff über Ports 220/21h wenn OPL3 erkannt wird, und es klingt genauso wie über die klassischen AdLib Ports. Das ist schonmal eine gute technische Basis.
Sollte es technisch bei einer OPL3 Hardware keinen Unterschied zwischen der Basis 388h und 220h geben, wäre die Ansteuerung über 388h natürlich einfacher umzusetzen, und das wird auch empfohlen.

Vielleicht sieht noch jemand grundsätzliche Optimierungsmöglichkeiten meiner derzeitigen Output-Routine:

Code: Alles auswählen

procedure write_reg; assembler;
(* AH: Data, AL: Reg *)
asm
  mov dx, oplbase
  out dx, al

  test dx, 080h
  jnz @opl2   (* jump to @opl2 if base is 388, not 220, 240 or 260 *)

  mov al, ah
  inc dx
  out dx, al
  dec dx
  in al, dx

  ret

  @opl2:

  (* delay for base/status register *)
  in al, dx; ... (-> 6x unrolled!)

  mov al, ah
  inc dx
  out dx, al
  dec dx

  (* delay for data register *)
  in al, dx; ... (-> 35x unrolled!)
end;
EDIT: Mir ist erstmal schon eingefallen, dass ich einfach Bit 7 von der Basis "TESTen" kann, dieses steht nämlich nur, wenn die Basis 388h ist und nicht 220, 240 oder 260. Da muss ich gar nicht noch zusätzlich den Boolean-Status "opl3_present" prüfen.

Und noch ein EDIT:
Ich werde das ganze über Codemodifikation lösen.
So kann die Routine dann immediates statt Speicherzugriffe nutzen, ein TEST und ein Sprung fallen weg, und ich verwende MOVs statt INC/DEC, so dass die Routine nur die Register AL und DX ändert und die Flags nicht beeinflusst.
mov ax, 13h
int 10h

while vorne_frei do vor;
Antworten