Beiträge von Jan1980

    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

    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

    Vielen Dank für die Antwort ! Der Jumper ist gesteckt, ich hab ja schon viele Disketten für andere Systeme geschrieben - 3,5“ und 5,25“.

    Momentan ist ein NEC FD1165-FQ Laufwerk dran, das Laufwerk ist neu, alte Lagerware. Das gute daran ist, dass es keine Wechselspannung braucht für den Motor.

    Ich hab auch noch zwei lose Shugart SA-801 da. Da muss ich dann wieder alles anders verkabeln und den trenntrafo dazwischen hängen, um das zu probieren.

    Ich vermute/befürchte, dass da irgendein Jumper am Laufwerk nicht passt ?!


    Gruss Jan

    Ich habe jetzt auch mal ein NEC 8" Floppylaufwerk an den Kryoflux mit passendem Adapter angeschlossen. Wenn ich den Kryoflux mit "dtc -c2" initialisiere, schreibt er mir "max track=41". Aber die Disketten haben natürlich 77 Tracks. Mit dem HXC Programm habe ich eine HFE File zu einem Kryoflux Stream umgewandelt und diesen dann mit "dtc -w -e76 -f<quelldateien>" auf ne Diskette geschrieben. Im Doppelfloppylaufwerk meines Imsai´s kann ich die Diskette nicht lesen. Dann hab ich am Imsai die Diskette formatiert und Mbasic drauf gemacht, das funktioniert natürlich. Diese Diskette wollte ich dann mit Kryoflux überschrieben, er "schreibt" auch 77 Tracks, aber an der Diskette ändert sich nichts. Danach ist immer noch Mbasic drauf...

    Die Steprate kommt mir auch, rein von der Optik her, zu hoch vor. Bei Track 76 ist er schon fast aus dem Fenster der Floppydisk raus. Evtl. steht das Ding auf Doublestep und ich muss singlestep einstellen ?! Aber warum zerstört er dann die Diskette nicht ? Ich kann Mbasic immer noch ausführen...


    Gruß Jan

    Ja, da haste natürlich Recht ! Das war auch mein Gedankengang - wenn man es über die Adresszähler machen würde, müsste er ständig kucken, wo er ist. Also polling, wie du schon sagtest.. Letzten Endes ineffizient und das Timing des Programms würde es gewiss nicht danken..


    Gruß Jan

    Das stimmt schon: Es ist oft ganz verblüffend anders gemacht, als man so denkt. Ist gewissermaßen eine Form von Magie oder Zauberei. :)



    PS: ich kann mir eigentlich gar nicht vorstellen, daß es nicht in dem Atari Videochip ein Register gibt, was die aktuelle Rasterzeile "weiß". Denn diese Variante mit dem indirekten Timer nach Vblank Interrupt ist schon irgendwie eine ganz schön eigenartige Sache; zwei verschachtelte Interrutpts für eine Farbinformation ist auch gut aufwendig.

    Es ist aber tatsächlich so. Der Videocontroller, also der "Shifter", hat dafür kein Register. Der Timer B zählt mit den Rasterzeilen, aber nicht von 0-199, sondern einfach immer weiter. Wenn ich also über den vblanc interrupt dem Timer B jedes Mal resette, friemele ich mir den Timer B um als Rasterzeilencounter... Das ist der Kenntnisstand bis jetzt. Ich habe auch schon einen Code dazu geschrieben. Aber bis jetzt flackert nur eine Rasterzeile in der Mitte...


    Grundsätzich ist es schwierig, da gute Informationen zum ST zu finden. Kein Vergleich zu anderen Retrorechnern, wo man ja quasi mit Tutorials bombadiert wird... Aber das macht es natürlich auch spannender.


    Gruß Jan

    Du musst das mit dem Schaltplan machen. Hier ein Beispiel:



    Bei diesem C64 Model ist pro Bit 1 RAM-Baustein verbaut. In dem grünen Kästchen habe ich markiert, welches Bit zu welchem RAM-Baustein geht. Also wenn das Problem zB das Datenbit 1 ist, was dein Tester mit einem "A" anzeigen würde, dann müsstest du den RAM-Chip an U9 erneuern.


    Es gibt auch C64 mit nur 2 RAM-Chips, die jeweils eine 4 Bit Wortlänge haben. Da gehst du genau so vor. Du musst immer im Schaltplan kucken, an welchen Chip da Datenbit geht..



    Gruß Jan

    Ja, um eine Rasterbar zu erstellen, mach ich das natürlich auch mit einer Tabelle.. Erstmal geht es jetzt darum einen sauberen Rasterzeileninterrupt hin zu kriegen.. :)


    Bzgl. Demos.. dieses ganzen Sinescroller etc. werden ja auch alle über Tabellen und Speedcode gemacht. Lange Zeit dachte ich immer, das würde in Echtzeit berechnet werden.. :D Aber dafür sind die Rechner ja viiiieeeeeel zu langsam...


    Bei Demos gilt oft: "....nichts ist, wie es scheint..."


    Gruß Jan

    Dann ist es ja nicht mehr weit bis zum Rasterbalken ... :)

    Ja, daran arbeite ich. Man muß halt auch immer die Zeit dafür haben :) ... Die Abfrage der Rasterzeile ist beim Atari ST etwas komplizierter als zB beim C64. Beim ST muß man parallel den Timer B laufen lassen, der die Zeilen mitzählt und dann erst an der richtigen Stelle auslösen... Da blick ich noch nicht ganz durch... dann muß ja auch immer noch das Timing stimmen, sonst siehts beschissen aus oder funktioniert überhaupt nicht...


    Gruß Jan

    Toller Rechner ! Aber "neidischer" bin ich auf die tolle Wohnlage ! :)



    Gruß Jan

    Ich habe jetzt mal ein kleines Programm geschrieben zum Thema Interrupt. Um genauer zu sagen, im Bezug auf den vertical blanc interrupt. Für die, die es nicht wissen.... Vertical blanc ist die Zeit, wenn der Elektronenstrahl unten rechts abschaltet, dann diagonal nach links oben wandert und dann wieder einschaltet. Diese Zeit kann man für Rechen- bzw. Programmroutinen nutzen. Die Vectoradresse ist beim Atari ST $70 für den vblanc. Wird ein verticalblanc ausgelöst (das sind bei einer 50 Hz Kiste 50 Mal in der Sekunde), wird jedes Mal diese Routine ausgelöst, deren Adresse an der Speicherstelle $70 steht.


    Um es nochmal zu sagen. Bei solchen Operationen muß der Prozessor stets im Supervisor-Modus sein - anderenfalls gibts Bomben...


    Ohne jetzt nochmal näher auf zB das Sichern von Auflösung und Palette etc. einzugehen, macht mein Programm folgendes:


    - Ändere die Farbe 15 (Schriftfarbe beim ST) auf weiß

    - Schreibe irgendwas auf den Bildschirm

    - Lese die die Sprungadresse aus der Vectoradresse $70 aus und sichere den Wert an einer definierten Speicherstelle

    - Schreibe statt dessen die Sprungadresse zu meiner vblanc Routine in die Vectoradresse $70

    - Endlosschleife.... hier schnurrt jetzt das Programm, bis man eine Taste drückt, dann beendet es..

    - Schreibe den Usprünglichen vblanc wieder zurück

    - Stelle Auflösung, Colorpalette wieder her

    - Beende das Programm.


    Während des Interrupts läuft dann folgendes ab.


    Die Hintergrundfarbe ist Farbnummer 0, das Register hat Word-Länge. Bei jedem vblanc wird der Wert in ein Datenregister gelesen und darin dann inkrementiert. Die oberen 13 Bit werden ausmaskiert, so dass das Programm nur mit den unteren 3 Bit arbeitet, die die Helligkeit für die Farbe blau beinhalten.


    Also wenn man das Programm startet steht da die ganze Zeit die Textmeldung in weiß und die Farbe blau wabert die ganze Zeit von dunkel nach hell..


    Im Anhang ist der Source und die TOS-Datei



    Gruß Jan

    Ich habe mich die letzten Tage viel damit beschäftigt und als aller erstes hatte ich ein "Grundgestell" programmiert, dass ich den ganzen Code nicht jedes Mal nochmal neu tippen muss.. Und includieren von Sources finde ich immer so unübersichtlich. Das Grundgestell beinhaltet folgende Subroutines, die man eigentlich immer braucht.


    1. Sichern von Auflösung und Farbpalette.

    2. Wieder herstellen von Auflösung und Farbpalette für einen sauberen Programmabschluß.

    3. Supervisor Modus einschalten

    4. User Modus einschalten

    5. Auf Tastendruck warten


    Es ist jetzt nichts bahnbrechendes. Ich hab erst vor 14 Tagen mit 68k Assembler angefangen, aber vielleicht hilft es ja dem ein oder anderen ?! Ich hab mir darin noch ein paar Notizen gemacht, die lass ich stehen... wir sind ja unter uns.. :)


    EDIT: ui, da hatte sich ein Fehler eingeschlichen... ich hatte mich vertippt und ein Word mit einem Longword vertauscht... Anbei die neue Version...


    Gruß Jan

    Ah ok. Es war ja nur ein Beispiel.


    Als kleine Ergänzung noch. Das war ja jetzt wieder ein "Vollbilld" mit 320x200 Bildpunkten. Gestern Abend hatte ich aber noch selber ein Bild erstellt. 320x200 Pixel schwarz und auf den schwarzen Hintergrund habe ich ein kleineres Bild eingefügt. Dieses Bild wurde wegen dem großen Schwarzanteil sehr klein im Speicher wegen der Kompression. Auf Anhieb habe ich es nicht hinbekommen, das daraus umgewandelt *.IFF File am Atari zu öffnen.

    Letzten Endes hab ich es hinbekommen. Man muß das Bild im Paint als 24 Bit Bitmap abspeichern und anschließend erst konvertieren. Dann hat es ungefähr 30kb und wenn man es als *.IFF konvertiert hat, lässt es sich problemlos am Atari öffnen und man kann es in Degas Elite als *.PI1 umwandeln..


    Gruß Jan

    Ich hab einfach mal ein Bild von deiner Website geklaut. Das zarte lila der Zimmerwand musste ich rausfiltern, da sonst das ganze Bild einen lila-stich gehabt hätte. Abfotografiert von einem Atari sc1224 Monitor.

    Ich hätte jetzt mit dem Dithering noch spielen können, um das Bild zu perfektionieren, aber es ging ja jetzt nur mal um ein Beispiel...



    Gruss Jan