Posts by Jan1980

    Ah jetzt rutscht der Groschen. Nehmen wir mal folgendes an:


    1. Es erscheint ein Startbildschirm, der das Programm bzw. den Namen desselben anzeigt und zum beginnen muß man eine Taste drücken.

    2. Der Counter läuft direkt los mit erscheinen des Startbildschirms.

    3. Die Zeit zwischen Programmstart und drücken der Taste wird immer eine andere und immer zufällig sein.


    Somit würde man schon zu Beginn des Spiels bzw. Programms das "Verhalten" desselben bzgl des späteren Verlaufs beeinflussen.


    Man könnte auch anstatt einem Register mehrere Counter in der Zeropage laufen lassen und dann daraus eine Zahl berechnen.


    So könnte man eine richtige Zufallszahl erzeugen lassen..


    EDIT: Man könnte parallel Counter in einem Register, in der Zeropage und in einer normalen Speicherstelle laufen lassen. Das Zählen wäre unterschiedlich schnell und daus könnte man eine Zahl errechnen.


    Gruß Jan

    Das Problem ist, dass die Zufallszahl ohne Äußere Einflüsse entstehen soll, d.h. ohne Tastendruck. Andernfalls könnte ich das mit einem Counter realisieren, wie von dir erwähnt.


    So würde er zB das X-Register andauernd dekrementieren bis man Space drücken würde, dann bekäme man eine Zufallszahl. Aber hier is wieder der äußere Einfluss im Sinne des Drückens der Space-Taste..



    Gruß Jan

    Vielen Dank für die ganzen Antworten. Einige Ideen hatte ich schon selber, zB die Abfrage der Paddles in Anbetracht des Rauschens. Die Idee mit der Abfrage des Diskettenlaufwerks ist interessant. Allerdings soll es funktionieren ohne Peripherie.

    Ich wollte das Programm Kaleidoskop von Basic nach ASM übersetzen. In Basic sind das ja nur ein paar Zeilen. In Assembler über ne DIN A4-Seite versteht sich. Im Grunde genommen nichts schwieriges wäre da nicht die Sache mit dem random.


    Bei anderen Systemen wüsste ich, wie ich die Routine verwirklichen könnte. Speziell beim Apple 2 aber nicht.


    Der Apple 2 hat:


    - Keine Rasterzeilenabfrage

    - Keine eingebaute Uhr

    - Keinen pseudo random generator

    - Keinen Timer

    - Tastaturabfrage über polling


    Anscheinend hatte es Woz nicht so mit Interrupts und Timern ?!


    In der Zeropage an den Adressen $4e und $4f ist die Ablage für rdkey/random Routine. Ich hab gestern Abend mal in das ROM Listing geschaut. Da wurde nur inkrementiert, geshiftet und dekrementiert. Also nichts halbes und nix ganzes. Ich schau mir jetzt erstmal die ganzen Links von euch an und wollte mal kucken wie Applesoftbasic RND realisiert.


    Achso. Die Zufallszahl soll eine Integerzahl zwischen $00 und $ff sein.



    Gruß Jan

    Hallo.


    ich übersetze gerade zum Spaß ein paar Basicprogramme in Assembler und bin auf der Suche nach einer Lösung, um Zufallszahlen zu generieren. In Basic ist das ja mit RND kein Problem. Aber wie mache ich das in Assembler ? Ich habe beim Apple 2 Plus keine Timer, geschweigedenn einen pseudo random generator. Das einzige was ich gefunden hatte war dieKeyin Subroutine $FD1B. Diese wartet auf einen Tastendruck und erzeugt eine Zufallszahl. Aber ich will nicht auf einen Tastendruck warten.. :)

    Evtl. finde ich bei dieser Routine ja die Lösung im ROM Listing. Oder hat einer von euch ne gute Idee, eine random routine zu programmierenß


    Gruß Jan

    Vielen Dank für die Links ! Bei meinem Apple 2 Europlus hatte ich ebenfalls vor einiger Zeit diesen Umbau bzw. die Rückrüstung zu Apple 2 Plus gemacht, der läuft ganz gut ! Den Thread bei jammarcade hab ich gelesen. Bei mir ist es so, dass ich die IOU 344-022A drin habe. Diese ist wohl für NTSC 50 hz. Wenn ich jetzt den IOU 344-020 hätte, dann könnte ich den Rechner vermutlich als 60HZ NTSC Rechner betreiben und er hätte vermutlich am NTSC Monitor Farbe.


    Ich habe das Problem mit meinem IIe auch - Meine Lösung ist RGB2HDMI, damit bekomme ich ordentlichen Farb-Output.

    Vielen Dank für den Tip ! Aber ich hab meine Retrorechner am liebsten am Röhrenmonitor. Eine "normale" RGB Karte zum Anschluss an einen CBM8833 Monitor wäre evtl. noch ne Alternative ?! Aber woher nehmen ?! :)


    Hier gibt ein US //e Farbe an ein Billig-LCD:

    Ja, das ist aber dann ein "reinrassiger" USA 60hz NTSC Rechner. Der sollte ja immer gehen mit passendem Monitor !

    Diese 50hz INTERNATIONAL NTSC Geschichte ist ja was außergewöhnliches. Da wollte Apple die eigenen Monitore verkaufen... :)




    Zwischenzeitlich war ich bei einem Kumpel, der ebenfalls viele Monitore hat. Da hatten wir auch noch probiert. Nichts zu machen. Also gibt es quasi 3 Möglichkeiten ?! :


    - Original Apple Monitor kaufen, restaurieren etc.

    - Board zu 60hz NTSC umrüsten mittels IOU 344-020

    - RGB-Karte


    Desweiteren gäbe es noch die Möglichkeit ein PAL-Board aus einem anderen Apple 2e zu entnehmen und in diesen zu bauen. Aber das möchte ich nicht.
    Ich denke mal, eine RGB Karte wäre am besten ?!



    Dieser Apple 2e mit Nummernblock ist ja so auf dem deutschen Markt nie erschienen. Meines Wissens nach sind auch der Apple 2c+ und der Apple 2gs ebenfalls nicht auf dem deutschen Markt erschienen. Ich denke, der neueste Apple 2 hier zu Lande war der Apple 2c. Aber auch dieser kann meinen Recherchen nach keine Farbe am Composite Anschluss ausgeben. Hierzu wird ein spezieller Adapter für den RGB Port benötigt, der dann wieder Composite (allerdings diesmal mit Farbe) und ein HF-Signal zum Anschluss an den Fernseher rauswirft. Dieser RGB Port ist digital. Ganz schöner hickhack.


    Jetzt die große Frage. Könnte man an einem Apple 2c RGB Port direkt einen Phillips CM8833 oder einen CGA Monitor betreiben ? Bzw. ist dieser Port Signalkompatibel mit zB dem RGBI Ports des Commodore 128 ? Das wär mal interessant zu wissen !



    Gruß Jan



    -

    Hallo.


    Ich habe einen Apple 2e mit Nummernblock bekommen. Die Rifas habe ich ausgetauscht, das Gerät läuft soweit gut. EInziges Problem, keine Farbe !

    Das Mainboard ist ein NTSC INTERNATIONAL Board und müsste die letzte Revision sein ( 1987 ). Ich habe den Rechner an mehreren Monitoren ausprobiert,

    die in der Lage sind NTSC und PAL darzustellen. Es handelt sich dabei um 2 verschiedene Sony PVM Monitore und einen JVC Studiomonitor. Normalerweise wird die Fernsehnorm auch angezeigt, aber in dem Fall ist das Signal anscheinend nicht identifizierbar für die Datensichtgeräte.

    Der Grafikchip bzw. die IOU hat die Bezeichnung 344-022. Diesen hatte ich auch mal in einen anderen 2e gesteckt, der is ok, da kommt Farbe.

    Jetzt habe ich irgendwo in den Tiefen des Internets gelesen, dass nur der dafür ausgelegte, originale Apple Farbmonitor dazu in der Lage wäre, Farbe in Verbindung mit dieser International-NTSC-Platine darzustellen.. Wie sind da die Erfahrungen ?



    Vielen Dank !


    Gruß Jan

    Cool ! Ich werde mir das mal anschauen später. Für meine Programme kann ich das gut gebrauchen. Aus gesundheitlichen Gründen konnte ich die letzten paar Monate nicht viel machen. Deswegen hab ich an dem Assembler-thread auch noch nicht weitergemacht. Ich brauch noch etwas Zeit, aber demnächst gehts weiter… 😊


    Gruss Jan

    Interessant zu lesen. Man müsste sich in dem Thread halt mal einigen, von welcher 1541 die Rede ist. Die alte 1541 hat keine Lichtschranke für Spur 0 Erkennung, die 1541C hat eine, diese kann man allerdings mit einem Jumper aktivieren bzw. deaktivieren. Die 1541 II hat eine Lichtschranke, diese ist nicht ohne weiteres deaktivierbar. Die Laufwerke haben (offziell) 35 Tracks, der Trackabstand wird bestimmt von der Rastung des Steppermotors. Die Track und Sektornummer steht im identifier jedes Sektors, deswegen braucht man auch keine Sektor 1 Lichtschranke bzw. das Index Loch wird nicht benutzt. (Sonst könnt man ja auch die Diskette nicht drehen und benutzen :) )

    Wenn die Laufwerkselektronik die aktuelle Position des Kopfes nicht kennt, werden immer 35 Tracks gestept richtung Track 0. Dh. wenn der Kopf physisch auf Track 35 steht, geht das ganze relativ geräuschlos von statten. Steht der Kopf allerdings physisch bei Track 10, dann rattert er noch 25 Mal gegen den Endanschlag. Durch dieses ständige Schlagen gegen den Endanschlag kann sich im Laufe der Zeit der Steppermotor dejustieren/verstellen/verdrehen, was eine Justage von Nöten macht.

    Wenn die Spurlage des Laufwerkes mittels einer Analogdisk mit den Cateyes eingestellt ist und der Azimuth ok ist (das ist der Winkel, in dem der Kopf zu der Diskette steht), dann stellt man den Anschlag ein. Du stellst das Laufwerk auf den Track 35 und lässt es dann initialisieren bzw. Track 0 anfahren. Da dürfte dann nichts zu hören sein. Steht der Anschlag zu stramm hörst du immer ein "knock" wenn er Spur 0 von Spur 35 kommend anfährt. Dann muß der Abstand vergrößert werden. Allerdings muß er Abstand kleiner als ein half track sein. Also kommt das hin mit dem Tip von Peter Sieg.


    Gruß Jan

    Ich hab vor einiger Zeit eingeschweisste Kodak 5.25" 2D Disketten gekauft bei ebay. Verpackungszustand top, angeblich trocken gelagert. Alle Disketten sind defekt, die Oxydschicht löst sich vom Träger - damit hab ich mir fast eine Floppy zerstört. Dann hatte ich hier bei jemandem aus dem Forum eingeschweisste Boeder 5,25" 2D Disketten gekauft, auch aus der Zeit. Die funktionieren alle einwandfrei !

    Meine 5,25" C64 Disketten von damals funktionieren alle noch, egal welche Marke - auch die nonames aus den weißen Schachteln für 10 DM damals. Meine 3,5" 2DD Disketten vom Atari ST funktionieren auch fast alle noch. Letztens hatte ich eine, die ging partout nicht mehr. Ich habe ca. 300 Disketten für den ST.

    Am negatisten sind mir mal Amiga Disketten aufgefallen, da liefen gefühlt 40 von 60 nicht mehr... warum auch immer - evtl wegen der etwas höheren Schreibdichte ?!

    Bei 8" Disketten hab ich keine Probleme mit BASF.


    Gruß Jan

    Hey, cool, dass du dich mit sowas auf dem ST ganz neu befasst! :mrgreen::thumbup: Gefällt mir! Bin gespannt, wohin es führen wird! ;)

    Mir ist es ganz wichtig, nicht nur zu sammeln, sondern auch, mich mit den Geräten zu befassen. In den letzten 2 Jahren habe ich 6502-und 8080/8085 Assembler gelernt, außerdem ein bißchen 8086 Assembler. 68k Assembler jetzt erst seit 4 Wochen. Der Atari ST war mein erster Computer. Ich habe zu Weihnachten 1991 einen 1040 STE bekommen. Zu meinem persönlichen Jubiläum "30 Jahre Atari" wollte ich den STe mal wieder etwas "würdigen" und habe mir gedacht, da jetzt auch mal was zu programmieren. Zu Hochsprachen finde ich irgendwie nicht hin. Eigentlich wollte ich C lernen am Atari. Aber irgendwie finde ich Assembler am meisten spannend !


    Selbstverständlich sind meine Codes nicht perfekt ! Allerdings ist es mir immer ganz wichtig, zu verstehen was ich mache.. Ich mache hier also kein blindes copy und paste mit vorhandenen Sources. Ich skizziere hier am Tisch den Programmablauf auf einem Blatt Papier und setze es dann in Code um.

    Wenn es läuft, ist es erstmal gut. Perfektionieren kann ich immer noch... Wichtig ist für mich erstmal, dass es funktioniert und dass ich es selber hinbekommen habe..


    Früher hab ich mich übrigens auch mal kurzzeitig mit Omikron-Basic beschäftigt. Bin dann aber relativ schnell zu GFA-Basic gewechselt. GFA-Basic ist super. Irgendwo hier hab ich sogar noch die ganzen Lehrbücher von damals aus der internetlosen Zeit.. :) Aber auch wenn ich es toll fand, will ich mich heute nicht mehr damit befassen..


    Gruß Jan

    Auf dem Atari ist das was, was eigentlich der Blitter machen kann. Wenn man weiß wie ...

    Ganz genau so ist es ! Bevor ich aber auf die Customchips und "Spezialfunktionen" der verschiedenen ST-Modelle eingehe, wollte ich erstmal im "Grundstock" programmieren. Viele STs haben gar keinen Blitter. Deswegen, eins nach dem anderen... :)


    Ansonsten: man kann die Schleife vereinfachen, indem man das Bild anders einliest - und zwar so, daß zunächstmal aller Zeilen des ersten Buchstabens hintereinander im Speicher liegen, dann nachfolgend alle Zeilen des zweiten Buchstabens usf. (dann klappt natürlich der Blitter nicht mehr, aber man spart ein paar Additionen für Wechsel in der Grafik).

    Außerdem kann die Tabelle auch einfach weiter vorn beginnen - dann muß man nicht die $20 subtrahieren. Da man niemals vorhat unterhalb von $20 was zu lesen, ist auch relativ egal was da drunter steht (unterhalb im RAM).


    Bzgl. der Tabelle war mein Gedankengang, dass ich dann letzten Endes ja 20 Longwords, bzw. 80 bytes unnötigerweise im Speicher hätte. Da dachte ich ne Subtraktion wäre eleganter, man muss den Rechner ja auch mal rechnen lassen... :)

    Wie ich das Bild anders reinladen kann, weiß ich nicht. Natürlich hört sich das plausibel an. Aber bedenke, dann müsste ich das Bild nochmal zwischen kopieren...



    Gruß Jan

    Ich hab wieder Zeit gefunden, ein bißchen weiter zu machen....


    Dieses Mal zwischendurch ein anderes Thema. Ein "Hallo Welt"-Programm, aber mal anders....


    Das Ziel war es, mit einem alternativen Zeichensatz zu arbeiten aus einer Fontdatei, welche Ziffern bzw. Buchstaben in einer Pixelgröße von 32x32 enthält. Sicherlich hat sich der ein oder andere schonmal gefragt, wie man eine große Schrift, ggf. als Laufschrift auf den Bildschirm bekommt. Man könnte jetzt irgendwie eine dementsprechende, vorgefertigte Grafikdatei einbinden, die den gewünschten Text enthält. Allerdings ging es mir darum, ein Programm zu schreiben, dessen Source einen "Klartext" enthält, der dann dementsprechend mit den grafischen Fontzeichen dargestellt wird...


    Da meine künstlerisch gestalterischen Fähigkeiten doch sehr begrenzt sind und ich eher "technisch kalt" bin, musste ich wieder auf "Diebestour" gehen und wurde auf der Suche nach schicken Fonts hier fündig:


    https://github.com/ianhan/BitmapFonts


    Die Wahl fiel auf diese File:



    32X32-F1.png


    Das PNG-File habe ich in GIMP wieder als IFF exportiert und am Atari in Degas Elite als PI1-Datei exportiert.


    Wenn man sich jetzt dieses Bild anschaut und eine ASCII-Tabelle daneben hält, wird man feststellen, dass die Zeichensetzung (jetzt mal abgesehen von den grafischen Spielereien) die gleiche Reihenfolge hat. Der Unterschied ist, dass diese Tabelle erst bei dem 32. ($20.) Zeichen ASCII anfängt, also SPACE.


    Also muß man im Grunde genommen nur den Ascii-Wert aus seinem Text-String laden und von diesem 32 subtrahieren, dann weiß man schon, welche bzw. die wievielte Zelle man aus der Grafik laden muss, um das dementsprechende Zeichen dar zu stellen.


    Jetzt ist es allerdings so, dass dieses Fontfile nur eine Grafikdatei, will heißen nur ein Bild, ist. Deswegen muß dieses erstmal in Zellen unterteilt werden, um dann später darauf zugreifen zu können. Dazu müssen wir kurz auf die Darstellung eingehen.


    Ein Zeichen ist 32x32 Pixel. Die Auflösung des ST´s ist 320x200. Der ST hat pro Scanline 160 byte. Geteilt durch 10 ergibt das eine Zeichenbreite von 16 byte !! Die Zeichenhöhe beträgt 32 byte. Um einen Buchstaben zu laden, muß ich also zwei verschachtelte Schleifen programmieren. Auf der x Achse werden 16 byte übertragen, dann werden in der Quelldatei und im Framebuffer 144 byte (160 byte insgesamt minus 16 byte Zeichenbreite) addiert. Somit springt er dann in die nächste Scanline wieder an den Anfang und ich kann erneut die X-Achsen-Schleife laufen lassen.


    Soviel zu der Darstellung bzw. zu dem kopieren der Grafik. Die große Frage war jetzt, wie ich das mit der Zellenunterteilung mache. Nun, ich habe ganz einfach eine Tabelle erstellt, die die Koordinaten der Buchstaben enthält gemäß der "Ascii-Reihenfolge".

    Jetzt ist es allerdings so, dass der ST eine Adressbreite von 24 Bit hat. Dem zu Folge konnte ich die Tabelle natürlich nicht in Bytes oder Words definieren. Ich musste die Tabelle in Longwords definieren. Nur so ist man in der Lage, die passende Adresse zu seinem Ascii-Zeichen an zu springen.


    Nächstes Problem... Wenn ich eine "1" darstellen will, ist das Ascii $31, wenn ich eine "2" darstellen will, ist das Ascii $32. Der Ascii-Wert wird also lediglich um 1 inkrementiert. Wir sind im nächsten Byte. Da die Tabelle aber aus Longwords besteht, reicht es nicht in das nächste Byte zu springen, man muß ins nächste Longword springen. Ein Longword besteht aus 4 bytes, also muß man das aktuelle Byte einfach mit 4 multiplizieren, dass er in der Tabelle an die richtige Stelle springt. Die elegantere Lösung ist hier ein zweifacher logical shift left... :)


    Also nochmal in Stichpunkten:


    - Lade den darzustellenden Buchstaben aus dem Textstring. zB ein 'A'

    - Dieses A steht im Speicher natürlich als $41

    - Subtrahiere $20. Das ergibt $21 = die 33. Stelle in der Grafik (siehe Bild) - ACHTUNG, wir fangen bei 0 an zu zählen !

    - Multipliziere das Ergebnis mit 4

    - Lade den Anfang der "Translation table" in das Adressregister

    - Addiere das obige Ergebnis zu dem Anfang der "translation table" und ermittele somit die Position des Buchstabens.



    Hier noch das Ergebnis:




    Bei diesem Programm ist es so, dass es immer nur in die erste Zeile schreibt. Es ist auch völlig egal, wie lange der Textstring im Source ist.

    Trotzdem habe ich eine kleine Prüfroutine eingebaut, welche tatsächlich erst später von Bedeutung wird. Nach dem Ende des Textstrings wird dieser mit dem Byte 00 abgeschlossen. Damit weiß das Programm, dass nichts neues mehr kommt. Also so, wie mit dem $ bei CP/M oder MS-DOS.

    Selbstverständlich ist der nächste Schritt, ein Textscroller zu programmieren und da ist diese Funktion natürlich von Bedeutung.



    Gruß Jan

    Endlich hab ich wieder etwas Zeit gefunden, um weiter zu machen. Nach Vertiefung der bisher gewonnen Erkenntnisse, wollte ich jetzt unbedingt ein kleines Intro programmieren mit Rasterblanken, Schrift, einer Grafik und Sound.... und habe es geschafft... :)


    1. Zu den Rasterbalken.


    Die Farbwerte für die obere Rasterbar stehen in Tabelle 1, die Farbwerte für die untere Rasterbar stehen in Tabelle 2. Wie man nun verschiedene Farben in einem einzigen Farbregister via Interrupt auf dem Bildschirm darstellen kann, war ja bereits klar (siehe oben).

    Die große Frage war jetzt, wie bzw. an welcher Stelle man den neuen Farbwert aus der Tabelle in das Farbregister lädt. Naheliegend ist da ja der horizontal blank interrupt. Die Vectoradresse für den hblank liegt beim ST an $68. Der Plan war, diese Vectoradresse zu verbiegen und damit in eine eigene hblank routine zu springen, die einfach den nächsten Farbwert aus der Tabelle lädt, um sie dann dementsprechend in der nächsten Scanline aus zu geben...


    Allerdings ist es beim ST so, dass der hblank-Interrupt die niedrigste Priorität in der IRQ Tabelle hat. D.h. jeder andere Interrupt ist wichtiger ! Eine Realisierung über den hblank ist mir nicht gelungen. Klar, ich hätte während dessen alle anderen Interrupts ausschalten können, aber dann wäre mein Timer IRQ ebenfalls futsch gewesen und der Code wäre definitv nicht gelaufen.


    Manchmal verrennt man sich in eine vermeindliche Lösung. Dabei war es letzten Endes doch so einfach. Ich habe die Adresse von der Tabelle in ein Adressregister geschrieben und diese mit jeder Scanline incrementiert und dann dementsprechend darstellen lassen. In dem Schleifenzähler befindet sich dann die Anzahl der Tabellenwerte. Da die Rasterbars sehr hoch sind, habe ich jeden Wert zweimal in die Tabelle geschrieben.



    2. Zum Text


    Den Text habe ich einfach mit der gemdos Routine 9 auf den Bildschirm geschrieben. Die Farbe des Textes kommt aus dem Farbregister 15. Dieses musste ich in jedem vblank refreshen, da sonst der Wert der Farbtabelle des Bildes noch drin gestanden hätte. Je nachdem, welches Bild man verwendet bzw. welche Farbtabelle das Bild verwendet, hätte die Textfarbe dann nicht mehr gepasst andernfalls.



    3. Zur Grafik


    Die Grafik habe ich natürlich hier geklaut. Das in Windows abgespeicherte png file habe ich auf einen, im Paint erzeugten ,320x200 schwarzen background gelegt. Dieses habe ich dann im GIMP geöffnet, die Farbpalette auf 16 Farben reduziert und es als *.IFF Datei exportiert. Am Atari habe ich dann in Degas Elite die IFF-Grafik geöffnet und dann wieder als *.PI1 File exportiert, welches ich gut im Assembler verwenden kann.


    Da ich oben und unten die Rasterbars habe, mußte ich nicht das komplette Bild in den Framebuffer laden, sondern nur die Anzahl der benötigten Scanlines. Diesen Offset musste ich natürlich an die "ladende Adresse" und an die "speichernde Adresse" schreiben, das ist soweit klar.


    Die große Frage für mich war jetzt allerdings, an welcher Stelle im Programm ich das Bild lade....


    Wenn ich es im Hauptprogramm lade, wird es durch die Interrupts zerstört, weil sich jedes Mal die Farbregister ändern. Also war ich davon überzeugt, das komplette Bild nebst Farbregistern in TimerB Interrupt zu laden und dar zu stellen. das Bild hat 140 Scanlines. Mit Schleifencode hab ich maximal 25 Scanlines dargestellt bekommen. Mit Speedcode habe ich 70 Scanlines dargestellt bekommen. Habe ich mehr Scanlines erzwungen, hat das ganze Bild geflackert.. Also auch doof..


    Nach einigen, weiteren vergeudeten Stunden meiner Lebenszeit bin ich dann auf die Lösung gekommen. Die Lösung ist, das komplette Bild inkl. passender Farbregister am Anfang zu laden... und dann im Interrupt jedes Mal nur die Farbregister zu refreshen.. :)



    4. Zum Sound


    Die Musik hab ich natürlich irgendwo geklaut. Dass in Demos die Musik anderer verwendet wird, ist ja gang und gäbe. Selbstverständlich gehört es da zum guten Ton bzw. es ist als Pflicht zu betrachten, den Programmierer/Komponist derselben wenigstens in der Demo zu erwähnen. Leider weiß ich in dem Fall nicht, wer die Musik gemacht hat und dem zu Folge kann ich es nicht angeben. Ich mache auch hier kein Tutorial, geschweige denn verfolge ich kommerzielle Absichten - ich teile lediglich meine Lernerfolge und auch die Rückschritte mit den Vereins-/Forums-Mitgliedern.


    Da es so schön einfach ist, habe ich in diesem Intro eine *.MUS-Datei verwendet. MUS-Dateien haben einen Player im header. Die Play-Routine wird im vblank jedes Mal aufgerufen. Initialisiert wird die Musik mit 1 im Datenregister D0 und anschließendem Anspringen der Musikdatei ohne irgendeinen Offset - beendet wird sie mit 0 im Datenregister D0 und anschließendem Anspringen der Musikdatei ohne irgendeinen Offset.




    Das Programm läuft zwar, ABER:


    Was mir noch gedanklich Probleme macht, ist das Timing der Interrupts. Wenn ich die Timer Zähler der Interrupts zusammen zähle, sollte ich doch auf 200 Scanlines kommen. Wenn ich die Schleifenzähler der Scanlines für die beiden Rasterbars und der Grafik zusammen zähle sollte ich doch ebenfalls auf 200 kommen. So funktioniert es aber nicht. Ich musste mit diesen Werten "spielen", um es hin zu kriegen.

    Klar, braucht der Computer auch zwischendurch Zeit, um das Programm an sich ab zu arbeiten, aber das müsste der ST doch schaffen mit 8MHZ.



    Hier noch ein Screenshot:




    Gruß Jan

    Stimmt,


    Die Lösung fand sich auch schon auf

    Seite 1,

    Ja genau. Wargames natürlich !


    Kurz nachdem ich diese Antwort damals geschrieben hatte, hatte ich ja dann doch einen Imsai 8080 gekauft und aufgebaut/restauriert/repariert. Siehe Nachbarthread... :)


    Gruß Jan

    Um eins vorab zu sagen . JA, ich finde es richtig, dass hier auf Themen wie Politik, Corona und Religion verzichtet werden soll !!!


    Nehmen wir zB folgenden Witz:



    Also ich persönlich habe laut gelacht ! Ich finde den Witz gut, es amüsiert mich !


    Das macht mich aber nicht automatisch zu einem schlechteren Menschen, das macht mich auch nicht automatisch zu einem "Italiener-nicht-mögenden-Menschen". Ich bin mir ganz sicher, dass die Italiener aus meinem Bekanntenkreis genauso gelacht hätten ! Da fühlt sich niemand angegriffen !

    Ich fühle mich auch nicht angegriffen, wenn jemand einen "sauerkraut" oder "kartoffelkopf"-Witz erzählt. Ihr wisst was ich meine ?!


    Diese "political correctness" hat meiner Meinung nach hier in Deutschland eine zu übereifrige Form angenommen ! Ich glaube, vor 20 Jahren wäre zu diesem Witz überhaupt kein "Diskussionsbedarf" da gewesen. Da hätte man kurz gelacht und gut. Man hätte diesen Witz wahrscheinlich gar nicht mit Politik verbunden, was ja auch quatsch ist, meiner Meinung nach.

    Aber hier in Deutschland haben die Leute ja Angst, schon aus der Tatsache heraus über einen solchen Witz zu lachen, direkt in eine politische Ecke gestellt zu werden.


    Also Ich bin mir ganz sicher, dass 1st1 und ich nicht die einzigen hier waren, die über den Witz gelacht haben. Aber auch gleichzeitig keine "politischen Hintergedanken" dabei hatten !! Aber das Lachen würden dei Leute ja nicht zugeben, weil man ja denken könnte, sie kämen aus einer politischen Ecke, was demzufolge evtl. ihrem Stand/Rang/wasauchimmer hier im Verein/Forum schaden könnte..


    "In Deutschland muß man mittlerweile zum Lachen in den Keller gehen..."


    Ich habe keine politischen Hintergedanken, ich habe über den Witz gelacht, ich finde ihn nicht geschmacklos und deswegen kriegt 1st1 jetzt dafür einen Like !


    Gruß Jan

    Hübsch, hübsch.


    Interessante Konstruktion. Verstanden hat man es wohl, wenn man weiß, warum beim zweiten Malen des Screens oben wieder mit rot angefangen wird - und nicht gelb weiterläuft.

    Ich habe auch bewusst ein Bild vom Monitor gemacht und keinen Screenshot vom Emulator gemacht, weil man da den Overscan sieht bzw. den Rahmen. Im Emulator geht es direkt oben mit rot los, denn die erste Rasterzeile ist ja rot. Weil der Atari diesen Rahmen hat, läuft das gelbe unten weiter und kommt oben wieder. Es gibt auch einen Trick, den Rahmen auf zu klappen und benutzbar zu machen.. Das steht hier schon auf der "to do"-Liste.. aber erst später mal... :)


    Die Variante mit dem Laden der Adresse in a0 und dann schreiben der Werte für die Rasterzeile indirekt sieht irgendwie eigenwillig aus. Kann man da nicht auch die z.B. #$80 direkt hineinbekommen - z.B. so ala move.b #$80,$adresse ??

    Code
        clr.b      $fffffa1b.w        ; Stop Timer*
        move.w     #$fa21,a0          ; Timer B counter address to reg A0
        move.b     #80,(a0)           ; Next Raster
        move.l     #new_timerb,$120   ; Set new vector address
        or.b       #$08,$fffa1b       ; Set Timer to event mode
        move.b     (a0),d0            ; Move value from Reg. A0 to D0
    wait_vbl: 
        cmp.b      (a0),d0            ; While value in Register A0 is the same like in Register D0...    
        beq        wait_vbl           ; DO NOTHING.. So, it waits for the next line.
        bsr        raster1            ; Branch to subroutine raster1

    Ich hatte es in der Tat vorher genau so, wie du beschrieben hast. Also "move.b #$80,$fa21". Das war bevor die "wait_vbl"-Schleife drin war. Diese bewirkt, dass er die Farbe noch nicht ändert, bevor die aktuelle Rasterzeile nicht ungleich der zählenden Rasterzeile ist. Sonst ändert sich nämlich die Farbe mitten in der Rasterzeile und da flackerts dann. Ich hätte also vor der Schleife den Wert aus dem Speicher dann lesen müssen, was einen weiteren/erneuten Speicherzugriff zur Folge hätte, welcher länger dauert als der Zugriff auf ein Register. Ich versuche immer möglichst viel in Registern zu arbeiten. Davon hat der 68k ja genug.


    Das ist aber nur die Nebenbemerkung. Viel interessanter wäre die Rasterzeile noch aus einer Tabelle auszulesen (man muß halt den Index "merken" und jeweils erhöhen). Und erst diesen Wert zu schreiben. Dann kommt man nämlich, in dem Fall eines Balkens, sehr schön schnell zu einer Animation - was ja vielleicht schon die gesuchte nächste Aufgabe sein könnte. ;)

    Ja, das ist richtig. Ich hab ja extra schon aus den Interruptroutinen in Subroutinen springen lassen, wo nur die Farbe 0 bzw. die Hintergrundfarbe gesetzt wird - zwecks Übersichtlichkeit. Die Farben dienen ja nur der Visualisierung - abgehackt in einer Farbe in voller Intensität, dass man klipp und klar sieht, wo es losgeht mit der dementsprechenden Routine. Selbstverständlich kann man hier auch eine Routine reinschreiben, die die Farben zB alle 2 Scanlines ändert, um so ein paar schöne Rasterbalken dar zu stellen. Aber eins nach dem anderen.. :)


    Gruß Jan

    So, ich hatte wieder etwas Zeit und ich habe nun eine Routine bzgl. Rasterzeileninterrupt programmiert. Zum grundsätzlichen Ablauf bzw. gewonnene Erkenntnisse:


    1. Die einzelnen Rasterzeilen, also die Scanlines werden von oben nach unten gezählt. Ganz wichtig ist hierbei von 0-199. D.h. die Gesamtsumme darf 199 nicht überschreiten, sonst flackerts !

    2. Der Vblank wird nach der letzten Scanline ausgelöst. Die Routine wird während des vblanks, also während der Elektronenstrahl von unten rechts nach oben links wandert, ausgeführt und startet dann ab der ersten Scanline.

    3. Der Timer B wird mit jeder aufsteigenden Scanline, also von oben nach unten, dekrementiert ! D.h., das Zählen ist hier gegenläufig. Wenn der Timer B bei 1 (NICHT BEI 0) angekommen ist, löst er die dementsprechende Routine aus, deren Vectoradresse an $120 steht.

    4. Der Timer B muss im Event-Mode, also Ereignismodus sein. Nur dann kann er als Rasterzeilenzähler funktionieren.

    5. Vor dem Setzen eines neuen Wertes für den Timer B, muß dieser durch das löschen die niederwertigsten Bits im Kontrollregister gestoppt werden.

    6. Der Timer C löst alle 5ms aus. Dieser muß deaktiviert werden, weil es sonst verticale Positionsstörungen der Rasterzeilen gibt.

    7. Ich habe eine ganze zeitlang nach einer Lösung zur horizontalen Sync gesucht. Das ist leider beim ST nicht ohne einen Trick möglich. Man lädt den Rasterzeilencounter aus der Timeradresse und vergleicht ihn mit dem gesetzten Wert. Vorher hat man den Timer aber wieder gestartet. Solange der Counter in der gleichen Zeile wie der gesetzte Wert ist, tut er erst mal nicht. Da aber im Hintergrund der Timer weiterläuft und erneut eine Zeile dekrementiert, ist das Programm in der Lage, diese Schleife zu verlassen und setzt erst dann die neue Farbe bzw, führt dann erst die gewünschte Subroutine aus. Das bewirkt, dass es erst in der nächsten Scanline los geht.



    Der Ablauf: (nur ein Beispiel, von der Farbdarstellung nicht im Bezug auf meinen Sourcecode unten)


    1. Im Hauptprogramm wird der Timer B eingerichtet. Auf Eventmode geschaltet und die Interrupts zugelassen.

    2. Vertical blank löst aus und setzt einen Counter in Timer B, zB mit dem Wert 40. Außerdem legt er die Routine in die vectoradresse für den (ersten) Timer B Interrupt fest. Wir setzen die Hintergrundfarbe auf rot.

    3. Jetzt wird er erstmal die ersten 40 Rasterzeilen in rot darstellen.

    4. Hat der Zähler dann den Wert 1, wird die Interruptroutine an Vectoradresse $120 ausgeführt.

    5. In dieser Routine wird der Timer gestoppt und auf einen neuen Wert, zB 50, gesetzt und wieder im Eventmode gestartet. Es wird die nächste Routine an die Vectoradresse $120 geschrieben. Wir setzen auf die Hintergrundfarbe blau.


    6. Bis jetzt haben wir 40 Scanlines in rot und dann 50 in blau.


    7. Hat der Zähler dann den Wert 1, wird die Interruptroutine an Vectoradresse $120 ausgeführt.

    8. Jetzt wird der Timer wieder gestoppt und wieder auf einen neuen Wert gesetzt, sagen wir 109. Wir starten wieder im Eventmode und setzen die Hintergrundfarbe auf grün. Hier setzen wir KEINE neue Routine an Vectoradresse $120. Wir haben ja jetzt 199 Scanlines dargestellt und es folgt der Vblank-Interrupt und es geht von vorne los.

    9. Wir sollten jetzt auf unserem Bildschirm 40 rote, 50 blaue und 109 grüne Scanlines sehen...


    ...mal schauen, was ich als nächstes programmiere.. :)



    Momentan beschäftigt mich noch das einbinden von Musik...


    Gruß Jan

    Hab vorhin mein Oszi aufgebaut. Wenn ich eine Diskette schreiben will, kommt von Seiten des Kryoflux nichts an am Pin "write data". Er springt nur periodisch zwischen low und high, keine Daten. Wenn ich allerdings eine Diskette mit dem Kryoflux lese, dann kommen bei "read data" Daten. Allerdings werden diese vom Kryoflux nicht "umgesetzt". Ich habe die ganze Zeit eigentlich immer über die Eingabeaufforderung gearbeitet. Jetzt habe ich mal über die grafische Oberfläche gelesen. Da habe ich dann DEC RX01 Sector Image verwendet und eine RAW Datei erzeugt. Track 00 liest er fehlerhaft. Ich kann zwar mit dieser Datei nichts anfangen, aber im Dump-Editor habe ich gesehen, dass er die anderen Tracks bzw. deren Sektoren gelesen hat.


    klaly: Welche Syntax nutzt du, um deine Disketten zu lesen ?


    Gruß Jan

    Ok, also mit exakt dieser Jumpereinstellung ging es jetzt auch nicht. Vielleicht is das Dingen ja auch einfach von Anfang an kaputt und war deswegen "NOS" ?! Dass hier aber auch kein Projekt vergeht ohne Oszi, Lötkolben etc.. Ich reiss mir jetzt ein Bier auf.. :D


    Auf der Diskette ist immer noch das Mbasic drauf. Es funktioniert auch noch. Also es fand überhaupt kein Zugriff seitens des Kopfes auf die Diskette zu..

    Ich versuche mit den Jumpereinstellungen jetzt mal ne Diskette zu lesen...


    Gruß Jan

    Also ich hab mir das jetzt mal in Ruhe nochmal angeschaut. Bei meiner Floppy ist RD gejumpert, dann sollte es doch gehen ?! Was hat das in dieser Anleitung mit den Patch-Kabeln vom Floppy Stecker Pin 48 und Pin 50 auf sich ? Da stand, der Stecker sei um 180° verdreht, aber das kann ja nicht sein, er fährt die Tracks doch an..


    Vielen Dank !


    Gruß Jan

    Ja, du hast Recht !



    Ich schau mir mal die Links von fritzeflink an, wenn ich nachher am PC bin.


    Gruß Jan