Allgemeine Hilfestellung zum Programmieren unter DOS gesucht

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

Re: Allgemeine Hilfestellung zum Programmieren unter DOS gesucht

Beitrag von DOSferatu »

zatzen hat geschrieben:Danke, DOSferatu, es ist immer gut wenn man genau Bescheid weiss. Also ist das Interrupt Flag so zu verstehen, dass die CPU(!) auftretende Interrupts abarbeitet oder nicht, aber sie reihen sich aneinander wenn sie nicht abgearbeitet werden, aber nicht mehrfach die gleichen. So habe ich das jetzt verstanden.
Naja, die Haredware-Interrupts haben eine (einstellbare) Priorität.
Und sie haben ein Register (ab AT eigentlich 2), wo ein Bit auf 1 gesetzt wird, wenn eine betreffende "Anfrage" (also ein IRQ) aufgetreten ist. Weil es nur ein Bit ist, kann also nicht herausgefunden werden, ob "in der Zwischenzeit" 2x oder 3x DERSELBE IRQ aktiviert wurde, sondern nur, daß mind. 1x aktiviert wurde.
Thomas hat geschrieben:Das mit dem Scancodearray interessiert mich jetzt näher:
Wie machst Du denn die Abfrage der einzelnen Tasten? Kann ich mir das etwa so vorstellen:
Wenn INT 16 dann lese scancode. Wenn bsp ESC, dann KeyArray[27] := 1 ?
Oder ist es doch etwas komplexer?
Naja, so ähnlich. Wichtig: Scancode hat nix mit ASCII zu tun. (ESC hat z.B. den Scancode 1.) Scancodes sind nur quasi "mechanisch" mit den Tasten verbunden - was der Grund ist, wieso bei uns Z den gleichen Scancode liefert, wie bei ner USA/UK-Tastatur das Y (weil die Taste an der gleichen Stelle steht). (Und was auch der Grund ist, wieso man bei rein USA-Spielen ne Abfrage wie "Quit DOOM [Y/N]" mit Z (statt Y) beantworten muß.)

Was aus den Scancodes die ASCII macht, ist der Tastaturtreiber - aber für ein interaktiveres Spiel will man ja nicht mit Tastaturpuffern arbeiten und diesem Taste gedrückt, reagiert 1x und nach ner Weile setzt die automatische Wiederholung ein... Das ist ja totaler Murks, wenn man damit ein Spiel steuern will - da gingen dann nur Tasten wie Shift/Ctrl/Alt usw., für die der Treiber zusätzlich Bits setzt, z.B. in $0040:$0017 (und z.B. $0040:$0096)...

Außerdem nehme ich für Keyboard-Abfrage IRQ9 (=INT 01).
Und dann wirklich genau so: Wenn INT kommt, dann bei PORT $60 gucken, was drinsteht (z.B. 42) und Scancode[42]:=1 setzen. Und wenn eine Taste LOSGELASSEN wird, kommt nämlich auch ein INT 01, und da steht dann der SCANCODE+128 (also gesetztes Bit7) drin und man kann Scancode[Taste and 127]:=0 setzen.

Für die "Sondertasten", die erst mit AT dazukamen (Cursortasten, rechte Alt+Ctrl, zweite Enter usw) gibt es einen "Präfix-Code" (224, also $E0), der sowohl beim Drücken als auch beim Loslassen vorher gesendet wird. Dann weiß man, daß danach eine "erweiterte" Taste kommt. (Anm.: Die "Multimedia"-Tasten, die manche Tastaturen haben, sind auch manche von denen...)

Und, weil man ja nun sieht, daß das Ganze nur für max. 127 Tasten (eher weniger) gebaut ist, 0 (null) z.B. nicht vergeben ist... weil ja das obere Bit für "Loslassen" benutzt wird, aber es eben "Erweiterte" Tasten gibt, mach ich der Einfachheit halber ein Feld von 256, und eine "erweiterte" trage ich ab 128 ein.

Und JA! Es würde auch ein BIT-Feld (von 256 BIT) statt 256-BYTE-Feld reichen - aber, es hat sich in der Praxis herausgestellt, daß die Abfrage (auch "indirekte" Abfrage usw.) eines 256-BYTE-Arrays einfacher ist. So "verschwende" ich 224 Bytes (also 256 statt 32), aber dafür spare ich an einigen Stellen komplizierteren CODE (der vielleicht insgesamt mehr als 224 Bytes bräuchte) UND bin bei Abfragen schneller.

Mit "indirekt" meine ich: Wenn ich ein Spiel baue, mache ich es immer mit freibelegbaren Tasten für die Spieler (außer ein paar, die man vielleicht für die Steuerung der Menüs oder so braucht), d.h. in der Spielsteuerung frage ich nur z.B. Taste 0,1,2,3 (für hoch/runter/links/rechts) oder Taste 4 (für springen) Taste 5 (für schießen), Taste 6 (für benutzen) usw. ab.... Und irgendwo extern lege ich fest, welcher Scancode z.B. für Taste 5 steht (und das kann man in einem Menü dann änderbar machen.

Zum Glück habe ich hier auch für alle Tasten die zugehören Scancodes da, auch als Liste und so.

Naja, und das mit dem Tastenarray mache ich u.a. auch deswegen, weil so auch mehrere Tasten gleichzeitig gedrückt abgefragt werden können - weil ja nicht irgendwas die ganze Zeit "AN" ist, wenn eine Taste gedrückt wird, sondern nur ein INT kommt, wenn eine Taste gedrückt wird (und danach zusätzliche INTs für die Tastenwiederholung, aber das spielt keine Rolle, ob man da NOCHMAL das Feld auf :=1 setzt, was es schon vorher war) und nochmal ein INT, wenn die Taste losgelassen wird. Und somit hat man ein Feld, das quasi alle Tasten enthält, die momentan gedrückt sind.

Wichtig noch anzumerken: Nicht alle Tastaturen erlauben es, unendlich viele ("alle") Tasten gleichzeitig gedrückt zu haben - da ist hardwaremäßig so gebaut, kann softwareseitig nicht umgangen werden (originale IBM-Keyboard haben das aber wohl mit "alle gleichzeitig" möglich).

Und dann wäre da noch die "Pause"-Taste. Die abzufragen ist ein bißchen "komisch", weil sie beim Drücken EINIGE Scancodes hintereinander sendet und beim Loslassen NIX. - Sie simuliert quasi das Drücken von Rollen und Num und Ctrl oder sowas gleichzeitig - weiß grad nicht auswendig. Früher (XT) gab es keine PAUSE-Taste, da wurde das durch 'ne Tastenkombi gemacht und bei AT hat man, damit es abwärtskompatibel ist, diesen Schlunz so eingebaut. Allerdings ist es erkennbar am Präfix-Code 225 ($E1). (Diese Präfix-Codes $E0 und $E1 würden XT-Rechner einfach ignorieren, deshalb hat man die genommgen. Es ist wie "Loslassen Taste 96 und 97 ($60 und $61)", die es nicht gibt.) Also kann man nur feststellen, ob Pause gedrückt wurde, aber nicht, ob sie festgehalten wird. Ist aber auch egal. Da kann man ein Flag setzen - die nimmt man sowieso nicht zum Steuern - aber zum Spiel anhalten reicht es.

So, das war wahrscheinlich wieder viel mehr Info als nötig.
Naja, ich sag's mal so: Prinzipiell mache ich seit Jahren (Jahrzehnten) das gleiche wie Du (Thomas) : Spiele unter MS-DOS in Pascal+Assembler programmieren, inklusivie eigener Subroutinen/Units usw. - (Kannst Dir ja mal "Xpyderz" angucken, wenn Du willst.) Und momentan bin ich gerade ein einer neuen zusammenfassenden "Engine" dran, die meine ganzen Sachen neu zusammenbaut: Sprite-/Levelanzeige, Erzeugung/Abspielen von Musik/SoundFX, Steuerung der Figuren (Spieler, "Feinde", Projektile, usw) durch einen in Assembler geschriebenen Bytecode-Interpreter... usw. Und dann eben auch so niedliche Kleinigkeiten wie den Keyboard-Interrupt mit diesen Scancodes oder den Timer-Interrupt für die Steuerung und die richtigen "Spielticks/Sekunde"... und so Zeug wie die ganzen verschiedenen (auch selbstge"tweak"-ten) Auflösungen, die man so mit Mode-X fahren kann... Naja, was eben alles so zusammenkommt, wenn man so einen Kram schon über 25 Jahre (auf PC) und fast 35 Jahre (insgesamt auf Computern) macht...
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: Allgemeine Hilfestellung zum Programmieren unter DOS gesucht

Beitrag von zatzen »

Hallo Thomas!

Ich sehe gerade, im Tracker selbst ist ja jederzeit ersichtlich, mit welchen F-Tasten man wohin kommt. Ich hatte das irgendwie total übersehen. Ich kenne mich mit Trackern gut aus und komme schon klar. Ich bastle mir dann mal Module mit denen ich die Abspielroutine teste...
mov ax, 13h
int 10h

while vorne_frei do vor;
Benutzeravatar
Thomas
DOS-Kenner
Beiträge: 426
Registriert: Mi 22. Jun 2016, 12:29
Wohnort: Nähe von Limburg / Lahn

Re: Allgemeine Hilfestellung zum Programmieren unter DOS gesucht

Beitrag von Thomas »

Danke für die Informationen, Dosferatu. Aber du meinst IRQ 1 und INT 9 oder?

Ja Zatzen, die Tasten sind auf dem jeweiligen Tracker Screen geprinted. Aber bei den F-Tasten war ich nicht sicher, da habe ich sie lieber mal hin geschrieben.
Ich schicke Dir meinen Stage Tune aber trotzdem zur Sicherheit noch mal. Evtl. Machst du 20 fehlerfreie Tracks aber meiner Zickt immer noch.
Ein bisschen DOS kann oft mehr als ein Haufen Fenster.

Gigabyte GA-586HX, P54C 100@75MHz, 24MB RAM, AVGA3-22-1M ISA, RTL8029AS PCI, Goldstar Prime 2 ISA, MA5ASOUND, Dreambl. X2 DB, HD 4x2GB, 48x CD, 3,5" Floppy, 2xRS232, 1xPar., PS/2 Maus
DOSferatu
DOS-Übermensch
Beiträge: 1220
Registriert: Di 25. Sep 2007, 12:05
Kontaktdaten:

Re: Allgemeine Hilfestellung zum Programmieren unter DOS gesucht

Beitrag von DOSferatu »

Thomas hat geschrieben:Danke für die Informationen, Dosferatu. Aber du meinst IRQ 1 und INT 9 oder?
Ja, genau. IRQ ist 1, und der ist auf INT 9 gemappt. Hab ich wohl versehentlich umgekehrt geschrieben.

IRQ 0 bis 7 sind auf INT $08 bis $0F gemappt, IRQ 8 bis 15 sind auf INT $70 bis $77. Man muß nur etwas aufpassen beim Bestätigen usw., weil IRQ 8 bis 15 quasi "über IRQ 2" gehen. Es sind 2 Interrupt-Controller-Chips drauf, jeder kann 8 IRQs. Deshalb sind die "chained", der zweite ist über IRQ 2 des ersten "durchgeschliffen". Aber

bei dem Kram, den wir hier machen (Real-Mode unter DOS/BIOS, wo die Sachen schon "gesetzt" sind), benutzen wir ja normalerweise nur die "unteren 8" IRQs: 0 (Timer) 1 (Keyboard) 5 oder 7 (Sound Blaster), da ist das mit den "oberen" nicht so wichtig.

Für Sound Blaster supporte ich derzeit sogar gar nichts über 7, obwohl man auch "höhere" stellen kann bei manchen. (Es gibt Leute, die haben 2 Soundkarten im PC und stellen für die zweite dann natürlich einen anderen Basisport, anderen DMA und anderen IRQ ein. Für mich war Soundblaster eigentlich immer Port $220, IRQ 5, DMA 1.)

Das mit dem "Bestätigen" ist nir wichtig, falls man den Ticker für mehreres mißbraucht - d.h. man hat einen ultraschnellen Ticker (z.B. 10 bis 20 kHz), um nebenher PC-Speaker oder LPT "digital" als Soundausgabe zu benutzen, davon abgeleitet vielleicht eine 50-100 Hz-Frequenz für die "Spiel-Schleife" (also wieviele "Schritte" pro Sekunde das Spiel macht) und zusätzlich geht es noch alle 18.2x pro Sekunde auf den "normalen" INT9, damit die Uhr noch richtig geht. Bei allem außer letzterem (was SELBST den INT/IRQ bestätigt/beendet), muß man ja vorher "rausspringen" und einen eigenen IRET machen - und davor muß man mit "mov AL,$20; out $20,AL;" den IRQ bestätigen, damit überhaupt neue kommen. (Für die "oberen" muß man "mov AL,$20; out $A0,AL" machen und ZUSÄTZLICH "out $20,AL", weil die, wie gesagt, "chained" durch die unteren, also durch IRQ2, sind.)

Man will ja schließlich nicht bei so 20000 Hz-Ticker (oder auch 100 Hz-Ticker), daß die normale INT9 Routine jedesmal mit ausgeführt wird. Nicht nur, weil die Uhr dann zu schnell geht, sondern auch, weil es zusätzlich Rechenzeit kostet, was bei 20 kHz schon etwas nerven würde...

Kleine Info für Spielecoding (weil's gerade paßt) :
Einfachste Möglichkeit ist, eine Word-Variable (Speicherstelle) zu nehmen und auf diese bei jedem Tick den Wert zu addieren, den man auch als 1/Frequenz-Wert benutzt hat beim Setzen der schnelleren Speaker-Frequenz. Und jedesmal, wenn der "überläuft" (also Carry=1), NUR DANN auf die normale INT9 weiterverzweigen - und ansonsten selbst beenden (mit IRET, und vorher obengesagter Port $20-Zugriff). Und, wichtig: Diese Word-Variable NICHT resetten oder sowas! Also NICHT, wenn Carry=1 ist, auf 0 stellen oder sowas. Denn dadurch, daß der 1/Frequenz-Wert etwas "krumm" ist, MUß dieser Überlauf ebenso sein, damit es am Ende wieder ca. 18.2 Hz werden. Erklärung dafür: Die 18.2 Hz entstehen, weil der Ticker standardmäßig auf einen Countdown von 65536 gesetzt ist (Der Wert ist 0, weil nur 16bit und wird hardwaremäßig im Ticker immer von 0 bis 0 "runtergezählt".) Dadurch ist der Wraparound bei der Variable bei 16bit genau passend, wenn man es mit niedrigerem Tickerwert macht. Je niedriger der ist, umso höher die Frequenz, weil er ja, um von 3 runterzuzählen weniger Systemticks braucht, als von 65536. (Wenn man als Wert 1 nimmt, hat er ne Frequenz von ca. 1,193182 MHz. Aber das muß das System natürlich auch abkönnen...)

Achja - ich und meine "Romane"...
Benutzeravatar
Thomas
DOS-Kenner
Beiträge: 426
Registriert: Mi 22. Jun 2016, 12:29
Wohnort: Nähe von Limburg / Lahn

Re: Allgemeine Hilfestellung zum Programmieren unter DOS gesucht

Beitrag von Thomas »

Man will ja schließlich nicht bei so 20000 Hz-Ticker (oder auch 100 Hz-Ticker), daß die normale INT9 Routine jedesmal mit ausgeführt wird. Nicht nur, weil die Uhr dann zu schnell geht, sondern auch, weil es zusätzlich Rechenzeit kostet, was bei 20 kHz schon etwas nerven würde...
Also soll ich am Ende der Playerroutine nicht die alte ISR vom Timer INT 08 anspringen? :-O
Zuletzt geändert von Thomas am Mi 29. Jan 2020, 20:19, insgesamt 1-mal geändert.
Ein bisschen DOS kann oft mehr als ein Haufen Fenster.

Gigabyte GA-586HX, P54C 100@75MHz, 24MB RAM, AVGA3-22-1M ISA, RTL8029AS PCI, Goldstar Prime 2 ISA, MA5ASOUND, Dreambl. X2 DB, HD 4x2GB, 48x CD, 3,5" Floppy, 2xRS232, 1xPar., PS/2 Maus
DOSferatu
DOS-Übermensch
Beiträge: 1220
Registriert: Di 25. Sep 2007, 12:05
Kontaktdaten:

Re: Allgemeine Hilfestellung zum Programmieren unter DOS gesucht

Beitrag von DOSferatu »

Thomas hat geschrieben:
Man will ja schließlich nicht bei so 20000 Hz-Ticker (oder auch 100 Hz-Ticker), daß die normale INT9 Routine jedesmal mit ausgeführt wird. Nicht nur, weil die Uhr dann zu schnell geht, sondern auch, weil es zusätzlich Rechenzeit kostet, was bei 20 kHz schon etwas nerven würde...
Also soll ich am Ende der Playerroutine hat nicht die alte ISR vom Timer INT 08 anspringen? :-O
Ja, 8 (Ticker) meine ich natürlich (was is nur heute mit mir los?)
Ja genau: Wenn der Ticker auf irgendwas außer 0 (also 65536) gesetzt ist, dann nur anspringen, wenn dieser o.g. Wraparound auftritt. Nehmen wir an, man will einen 50 Hz-Ticker. Dann ist der Wert auf den man den Ticker setzt 23863 oder 23864. (Genauer wird es nicht, weil die "Hauptfrequenz" 1/4 der berühmten 4,77.. MHz ist, also ca. 1193182 Hz.)

Und dann, jedesmal am Ende seines eigenen Tickers addiert man die 23864 zu einer Word-Speicherstelle. Und nur, wenn beim Addieren mal Carry kommt, springt man zum ursprünglichen INT-8 Vektor. (Den hat man sich ja, Zwecks Wiederherstellung, sowieso irgendwohin gesichert.) Und wenn KEIN Carry kommt, beendet man selbst. Natürlich ist das dann so, daß zwischen den "eigenen" (Spieler-)Ticks entweder 2x oder 3x der "normale" (die Uhr) aufgerufen wird, aber es ist im Schnitt genauso oft (also diese 18,2064... mal pro Sekunde). Das kommt natürlich daher, daß 50 und 18,2064... zueinander teilerfremd sind. Würde man als eigenen Tickerwert 32768 nehmen, dann würde GENAU jedes 2. Mal der "normale" angesprungen werden und man hätte eine "Spielfrequenz" von 36,4128... Hz. (also 18,2064... *2)

Aber das muß man nicht teilergenau machen, weil es, damit die "Uhr" (also $0040:$006C) richtig geht, ausreicht, wenn sie durchschnittlich diese 18.2... pro Sekunde aktiviert wird. Erklärung dazu: Auch der normale IRQ ist nicht total exakt, sondern nur "im Schnitt" - warum: Naja, ein IRQ wird nur ZWISCHEN zwei Opcodes (also zwischen zwei CPU-Befehlen) ausgelöst - nicht mittendrin. Also ist da auch immer ein leichter Versatz von ein paar Taktzyklen, der sich dann durch andere wieder ausgleicht.

Also ist hier auch eine Spielfrequenz von 50, 100 oder wasweißich Hertz total OK.

(Nutzlose Zusatzinfo, kannst auch überlesen:
Xpyderz setzt den Ticker sogar auf 400 Hz, funktioniert aber effektiv mit 50 Hz Spielschleife und bearbeitet pro "Tick" nur jede 8. Figur. Damals hielt ich das für eine gute Idee, und zwar aus dem Grund: Es sollte mal Multiplayer werden. Und die Spieler würden im ersten der 8 Ticks ihre "Steuerwerte" senden und im letzten der 8 Ticks diese empfangen (von den anderen), so daß die Zwischenzeit dafür wäre, daß die Daten rüberkommen. Da hatte ich noch so eine Konstruktion von mehreren, durch Nullmodemkabel verbundene Rechner im Sinn - später dann in möglicher Kombination mit TCP/IP... so art dezentrales Pseudo-Netzwerk... Aber was ich da zusammengebaut habe, war viel zu kompliziert - riesige Routinen, die bitweise das Zeug zusammenstellen und auf der anderen Seite auswerten... und das alles damals noch in Pascal... Ich meine: Ich würde zwar schon gerne auch heutzutage noch mal ein Multiplayer-Spiel machen - oder Xpyderz dahingehend "neu bauen" - aber das würde ich heute wohl ganz anders planen. Allerdings hatte ich damals auch mehr Kraft und Zeit. Heute komme ich vor Planerei kaum noch zum Programmieren - und vor Müdigkeit oft auch nicht mal zum Planen... - Warum das mit den Spielerwerten geht, liegt daran, daß alle Figuren außer den Spielern sich in der gleichen Situation immer auf die gleiche Art verhalten würden und diese Daten deshalb nicht übertragen werden müßten. Selbst ein "Zufallsgenerator" ist ja vorhersehbar, weil er vom selben Seed ausgehend immer die gleichen Folgen liefert.)

So, nochmal zum Keyboard:
Genauso kann man es übrigens mit INT 9 (Keyboard) halten.
Erstens: WENN man den anspringt, wird ZUSÄTZLICH zu dem, was man selber machen will (Scancode lesen, Taste zum Steuern von Spielfigur verwenden), ja die normale Tastenabfrage (also quasi der Keyboard-Treiber) mit ausgeführt. Und was macht der? Füllt bei jedem Tastendruck den Keyboard-Buffer weiter. Wenn der voll ist, fängt's häßlich zu piepen an bei jeder weiteren Taste. Also dann ENTWEDER immer gleich mit den Keyboard-Buffer leeren, wenn man das macht ODER gleich selber rausspringen. Allerdings ist dann sowas wie "Namen eingeben" oder ähnliches auch selbst zu machen.

(Ach ja: Wenn man selbst rausspringt - also den Keyboard-Treiber quasi umgeht - funktioniert auch der Affengriff (CTRL-ALT-DEL) nicht mehr und auch kein CTRL-C oder CTRL-Pause... Man kann das natürlich auch kombinieren und gezielt blockieren...)
Benutzeravatar
Thomas
DOS-Kenner
Beiträge: 426
Registriert: Mi 22. Jun 2016, 12:29
Wohnort: Nähe von Limburg / Lahn

Re: Allgemeine Hilfestellung zum Programmieren unter DOS gesucht

Beitrag von Thomas »

OK, aber ist das mit einem eigenen Word Zähler nicht unnötig kompliziert? Kann ich nicht einfach am Ende des Hauptprogramms die Systemuhr mit dem Wert der RTC wieder richtig setzen? Vorausgesetzt ich benötige keine halbwegs exakte Uhrzeit innerhalb des Programms.
Ein bisschen DOS kann oft mehr als ein Haufen Fenster.

Gigabyte GA-586HX, P54C 100@75MHz, 24MB RAM, AVGA3-22-1M ISA, RTL8029AS PCI, Goldstar Prime 2 ISA, MA5ASOUND, Dreambl. X2 DB, HD 4x2GB, 48x CD, 3,5" Floppy, 2xRS232, 1xPar., PS/2 Maus
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: Allgemeine Hilfestellung zum Programmieren unter DOS gesucht

Beitrag von zatzen »

Hallo Thomas!
Ich habe eine neue Version: http://www.zatzen.net/btplay8a.zip
Ich glaube jetzt müsste alles stimmen, teste das doch mal bitte, dann kann ich anfangen,
die Abspielroutine Stück für Stück in Assembler umzuwandeln und zu optimieren.
mov ax, 13h
int 10h

while vorne_frei do vor;
Benutzeravatar
Thomas
DOS-Kenner
Beiträge: 426
Registriert: Mi 22. Jun 2016, 12:29
Wohnort: Nähe von Limburg / Lahn

Re: Allgemeine Hilfestellung zum Programmieren unter DOS gesucht

Beitrag von Thomas »

OK, wird gemacht.
Ein bisschen DOS kann oft mehr als ein Haufen Fenster.

Gigabyte GA-586HX, P54C 100@75MHz, 24MB RAM, AVGA3-22-1M ISA, RTL8029AS PCI, Goldstar Prime 2 ISA, MA5ASOUND, Dreambl. X2 DB, HD 4x2GB, 48x CD, 3,5" Floppy, 2xRS232, 1xPar., PS/2 Maus
DOSferatu
DOS-Übermensch
Beiträge: 1220
Registriert: Di 25. Sep 2007, 12:05
Kontaktdaten:

Re: Allgemeine Hilfestellung zum Programmieren unter DOS gesucht

Beitrag von DOSferatu »

Thomas hat geschrieben:OK, aber ist das mit einem eigenen Word Zähler nicht unnötig kompliziert? Kann ich nicht einfach am Ende des Hauptprogramms die Systemuhr mit dem Wert der RTC wieder richtig setzen? Vorausgesetzt ich benötige keine halbwegs exakte Uhrzeit innerhalb des Programms.
Ja, daran habe ich auch schon gedacht. (Und, die CMOS-Ports auszulesen und das in die "Uhr"/"Datum" reinzuschreiben, ist auch kein Hexenwerk.)

Aber, ich weiß nicht, was genau die originale INT8-Routine macht, ob die außer Uhr weiterzählen noch andere Sachen (eventuell wichtige) macht oder nicht. Ich habe mit so eine generalisierte "Rahmen" Routine gebaut, die das übernimmt (d.h. Ticker mit wählbarer Frequenz eine Subroutine aufrufen und die originale ISR mit Orginalfrequenz (18,2 Hz) aufrufen.

Und ja, man könnte es seinlassen, aber zwei Befehle (ein ADD und ein JC) finde ich nicht "unnötig kompliziert". Wie gesagt, der Wert im Zähler wird nirgends ausgewertet, es geht nur darum, zu springen, wenn die Addition zwischendurch mal 'n Wraparound erzeugt (und somit das Carry setzt).

Naja, es war auch nur ein Vorschlag - prinzipiell kann man das auch machen wie man will. Ich gebe manchmal einfach zu Themen wahllos noch zusätzlich Informationen bei, die aus meiner Praxis und Erfahrung stammen, für den Fall, daß es jemanden interessiert (soll vorkommen).

Auch das mit der Tastenabfrage - da gibt es sicher viele Wege. Mir ist das mit diesem Tastenarray ganz genehm, weil ich damit für jedes meiner Spiele dem Spieler die Wahl lassen kann, die Tasten zur Steuerung frei zu belegen - ich finde, das wird immer noch viel zu selten bei so privat "selbstgemachten" Spielen gemacht. Die meisten "kommerziellen" Spielehersteller haben es nach Jahrzehnten begriffen, daß selbstbelegbare Steuerung und verschiedene Steueroptionen eine gute Idee sind - und daß teilweise der Erfolg eines Spiels auch an seiner Spielbarkeit liegt.

Was nützt die schönste Grafik, wenn einem die Steuerung nicht behagt und man sich damit abquält, weil irgendein Programmierer seine persönlichen Steuer-Präferenzen allen Spielern aufzwingt, die das spielen? Hatte echt schon Spiele erlebt, die man mit A/Z und O/P steuern mußte und als wäre das nicht schon schlimm genug, waren die USA/UK und nicht scancode-basiert (also mußte man das Z oben nehmen, nicht unser Y)...

Ich selbst z.B. kann WASD-Steuerung überhaupt nicht ab, ich will die Cursortasten zum Steuern haben. Aber in Xpyderz kann man für jede Funktion einstellen, welche Taste man dafür haben will UND es gibt 2 Steuermodi (den "Arcade"-Mode, wo man hoch/runter/links/rechts fährt - in die Richtung der TAste - und den "Cruise"-Mode, wo man vorwärts/rückwärts fährt und sich mit links/rechts dreht. Ich selbst favorisiere den ersteren - aber habe trotzdem extra diesen "Cruise" auch eingebaut, weil ich weiß, daß manche Spieler so lieber spielen.

Ich denke dabei immer, daß man quasi "gegen das Spiel" (also die Gegner, das Level, die Zeit, usw.) spielen soll und nicht der schlimmste Gegner schon die Steuerung sein soll. Die muß intuitiv sein - eigentlich soll man beim Spielen gar nicht auf die Tastatur schauen müssen... Achja, seit 'ner Weile supporte ich auch diesen PC-Joystick (Gameport), der wird bei mir "digital" in "virtuelle Tasten" umgewandelt.

Und meine neue "Spiel-Engine" (bzw. es sind mehrere Engines, die zusammen das Gesamtpaket ergeben) enthält schon alles, was ich mir über die letzten Jahre/Jahrzehnte erarbeitet habe (keine fremden Librarys, alles Eigenbau...) Wenn das mal alles zusammen funktioniert und dann auch wirklich so performt, wie ich mir das vorstelle, kann man damit großartige 2D-Spiele machen.

Wie ich ja so mitlese, bist Du gerade an einem Shoot'em'up dran. (Eins meiner geplanten Spiele soll übrigens auch sowas werden, Marke R-Type/Katakis.) Gibt es da schon irgendwelche Demos/Screenshoots o.ä. zu bewundern?
Benutzeravatar
Thomas
DOS-Kenner
Beiträge: 426
Registriert: Mi 22. Jun 2016, 12:29
Wohnort: Nähe von Limburg / Lahn

Re: Allgemeine Hilfestellung zum Programmieren unter DOS gesucht

Beitrag von Thomas »

Guten Abend, Dosferatu.
Ich wollte Deine Vorgehensweise in keinster Weise kritisieren, im Gegenteil, ich bewundere Deine Arbeit und ich kann sehr gut nachvollziehen dass man ein Stückweit stolz ist auf das was man entwickelt hat, vorallem wenn es alles aus der eigenen Feder stammt und nicht wie bei mir, überwiegend mit Hilfe einer fertigen Bibliothek. Es sollte jeder nach seinem Gusto machen und ich finde Dein Vorgehen mit dem Key-Array durchaus praktikabel.

Was den Zähler betrifft, für MICH sind so zwei OpCodes schon kompliziert, da ich kein Assembler spreche. (J)ump (if) (C)arry verstehe ich zwar (ADD natürlich auch) aber wenn ich das jetzt alles umsetzen sollte, so muss ich passen. Wenn mich nicht alles täuscht, so gibt Ralph Brown's Interruptlist nicht mehr her als den Timer Tick, INT 08 betreffend. Es SOLLTE also sonst nichts wichtiges ausgeführt werden. Ich wollte das mit dem Zähler auch nicht abtun, ich werde mich sogar damit beschäftigen weil mich das auch interessiert.

Ja, es gibt eine spielbare Demo von Alien Avenger. Ich wollte die eigentlich hier an Heiligabend veröffentlichen, habe dann aber doch einen Rückzieher gemacht. Ich wollte noch ein einzelnes großes Datafile machen statt einzelner Grafik-, Sound- etc. Files aber dann hat BASIC rumgezickt. Einen eigenen Installer wollte ich auch noch machen. Ein echter Abspann fehlt auch noch und, und, und...
Aber es wird bald kommen, versprochen. :-)
Hat aber keine frei wählbare Steuerung... :-(
Ein bisschen DOS kann oft mehr als ein Haufen Fenster.

Gigabyte GA-586HX, P54C 100@75MHz, 24MB RAM, AVGA3-22-1M ISA, RTL8029AS PCI, Goldstar Prime 2 ISA, MA5ASOUND, Dreambl. X2 DB, HD 4x2GB, 48x CD, 3,5" Floppy, 2xRS232, 1xPar., PS/2 Maus
Benutzeravatar
Thomas
DOS-Kenner
Beiträge: 426
Registriert: Mi 22. Jun 2016, 12:29
Wohnort: Nähe von Limburg / Lahn

Re: Allgemeine Hilfestellung zum Programmieren unter DOS gesucht

Beitrag von Thomas »

Zatzen, der Fehler der irrtümlich gespielten Strings ist leider immer noch drin... :-(
Ein bisschen DOS kann oft mehr als ein Haufen Fenster.

Gigabyte GA-586HX, P54C 100@75MHz, 24MB RAM, AVGA3-22-1M ISA, RTL8029AS PCI, Goldstar Prime 2 ISA, MA5ASOUND, Dreambl. X2 DB, HD 4x2GB, 48x CD, 3,5" Floppy, 2xRS232, 1xPar., PS/2 Maus
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: Allgemeine Hilfestellung zum Programmieren unter DOS gesucht

Beitrag von zatzen »

Hallo Thomas, dann brauche ich mal die PIS Datei per email (zatzen bei googlemail.com) und ne Angabe an welcher Order und Row der Fehler passiert.
mov ax, 13h
int 10h

while vorne_frei do vor;
Benutzeravatar
Thomas
DOS-Kenner
Beiträge: 426
Registriert: Mi 22. Jun 2016, 12:29
Wohnort: Nähe von Limburg / Lahn

Re: Allgemeine Hilfestellung zum Programmieren unter DOS gesucht

Beitrag von Thomas »

Ja, ich schau mal dass ich es morgen sende. Die Ordr Angabe hatte ich bereits gepostet weiter oben (Pos 5, Zeilen 50-52 und Pos 9, Zeilen 50-52). Ist echt seltsam... Ist nur bei dem Track aber mit der BASIC PISplay und im Tracker ist alles korrekt...
Ein bisschen DOS kann oft mehr als ein Haufen Fenster.

Gigabyte GA-586HX, P54C 100@75MHz, 24MB RAM, AVGA3-22-1M ISA, RTL8029AS PCI, Goldstar Prime 2 ISA, MA5ASOUND, Dreambl. X2 DB, HD 4x2GB, 48x CD, 3,5" Floppy, 2xRS232, 1xPar., PS/2 Maus
Benutzeravatar
zatzen
DOS-Guru
Beiträge: 518
Registriert: Di 17. Apr 2012, 05:10
Wohnort: bei Köln
Kontaktdaten:

Re: Allgemeine Hilfestellung zum Programmieren unter DOS gesucht

Beitrag von zatzen »

Kleines Update, falls doch noch Fehler in der Wiedergabe auftreten:
Pascal legt die Variablen ab 16 Bit Breite standardmäßig an geradzahligen Adressen an, und das ist auch gut so. Nur sollte daher in der Routine read_ptn_row(ptn: word) etwas geändert werden, direkt am Anfang, da sonst unbekannte Speicherbereiche beschrieben werden und die eigentlichen verfehlt werden:

Code: Alles auswählen

  mov di, ptn
  
  mov n, 12
  db 66h; xor ax, ax
  db 66h; mov ds:[offset o], ax
  mov ds:[offset o + 4], al
  
  ...
ersetzen durch:

Code: Alles auswählen

  mov di, ptn
  
  mov n, 12
  mov o, 0
  mov eh, 0
  mov el, 0
  mov i, 0
  
  ...
EDIT: Hat sich mit dem Post von Version 9a erledigt.
Zuletzt geändert von zatzen am So 2. Feb 2020, 00:42, insgesamt 1-mal geändert.
mov ax, 13h
int 10h

while vorne_frei do vor;
Antworten