Bildschirminhalt in RAM sichern (CBM4032/8032/etc)

  • Juhu Burschen!


    Jetzt- in dieser merkwürdigen Zeit- bin ich gerade wieder am Ringpuffer-Spieleprogrammieren. :stupid:


    Dazu habe ich eine Frage, die evtl. für viele andere Projekte auch interessant sein könnte:

    Besteht die Möglichkeit, in Basic den Inhalt des Bildschirms in den Ram zu sichern, um ihn relativ flott wieder zurückholen zu können?

    Meine Idee wäre, einfach mit PEEK(32768+x) alle relevanten Stellen abzufahren und sie mit POKE 32768+x wieder ins Leben zu holen.

    Aber erstens ist dies zeitintensiv in Basic, und zweitens weiß ich nicht, ob es da eine Möglichkeit gibt, welche weit weniger Variablenspeicher benötigen würde?


    Danke schon mal für euren Input, Ringpuffer nimmt langsam Gestalt an, ich bin jedoch gerade am Bau eines Leveleditors, damit jeder der geneigten Mitforisten selbst welche basteln und dann zocken kann.


    Viele Grüsse,

    Matthias

  • Besteht die Möglichkeit, in Basic den Inhalt des Bildschirms in den Ram zu sichern, um ihn relativ flott wieder zurückholen zu können?

    Ja natürlich.

    Sind ja auch nur 1K RAM (bzw. 2K bei 80 Zeichen)


    Manche Erweiterungen bieten von vornherein 4 Seiten Bildschirm, die man umschalten kann.


    Allerdings würde ich zwei Mini Assembler Routinen vorschlagen (geht viiiiel schneller).

    Die vom BASIC aus mit SYS oder USR() aufgerufen werden ...



    Aber erstens ist dies zeitintensiv in Basic, und zweitens weiß ich nicht, ob es da eine Möglichkeit gibt, welche weit weniger Variablenspeicher benötigen würde?

    Man kann das schon in Variable ablegen.

    Zum Beispiel in einem String Array.

    Aber das macht es etwas komplizierter.


    Ich würde den BASIC Speicher oben etwas abschnippeln (HIMEM) und das als Buffer verwenden

    • Offizieller Beitrag

    Das geht mit der SAVE-Routine im ROM, wie sie auch vom TIM aus ausgerufen wird.

    Dann liegt das als PRG auf Disk, und kann mit (D)LOAD wieder direkt in den Bildschirmspeicher geladen werden.

    Aber... Wie werden Dateiname, Gerätenummer, Start- und Endadresse übergeben... die müssen irgendwo abgelegt werden, und dann die Routine mit SYS aufrufen.

    Ich habe das früher auch genutzt, aber wie das genau war, weiß ich nicht mehr.

  • Jungs, vielen Dank für den Input!


    Die Frage ist nun, wie ich das umsetzen kann?

    Hintergrund: Der Leveldesigner läuft schon so weit, allerdings würde ich gerne ein Hilfemenü aufrufen, indem die Tastenbelegung und Bedienung erklärt wird. Wenn man dies macht, ist natürlich das gezeichnete Level weg. :(

    Es klappt zwar bereits, das Level zu laden/speichern- aber ich würde es ungern jedesmal nach Aufruf des Hilfebildschirms neu laden müssen.


    Zum Thema laden/speichern bin ich aktuell auch noch nicht zufrieden... ein Level hat gute 17 blocks, da ich den Wert einer jeden Speicherzelle des Bildschirms wegsichere. :D

    Hier werde ich die einzelnen Zeilen noch in Strings umwandeln und diese (wären 21 Strings á 38 Zeichen) dann sichern. Sollte deutlich weniger Platz benötigen.


    Viele Grüsse,

    Matthias

  • Burschen!


    PETSPEED klappt! :sunny:

    Somit wird die ganze Thematik ein wenig entzerrt- weil das Teil so flott ist, dass man evtl. doch Zeichen für Zeichen speichern kann.


    Hierzu musste ich das Image von PetSpeed aus dem WWW auf SD-Karte kopieren, damit lief es aber nicht auf dem 4032.

    Also flugs in den Bastelkeller gefahren und den 8032 aufgebaut, sowie an die 8250 (und ans petSD+) geklemmt.

    Leider lief es so auch nicht- ein Eintrag aus dem Forum64 brachte Klarheit: Es funzt anscheinend nur mit der 8050.

    Und genau so war's: Nach Umbau auf Toast_r 's 8050 kompilierte PetSpeed einwandfrei:



    Nachteil: Das Programm wurde DOPPELT so groß, wird also selbst mit 16kB schon knapp werden (muss ich testen).

    Vorteil: VERDAMMT, ist das nun flott! :stupid: Ringpuffer war unspielbar, die Schlange war schneller an der Wand, als man kucken konnte.

    Leider wird auch der Sound entsprechend beschleunigt, weshalb man für den Einsatz mit PetSpeed alles umprogrammieren müsste.

    Mal sehen, was ich da noch mache... man könnte deutlich mehr Abfragen in die Schleife basteln.


    Zum Thema zurück: Eine Routine zum Bildschirm-Wegsichern und umgehend wieder laden wäre wirklich genial... ;)

    Vielleicht hat irgendwann mal Jemand den zündenden Codeschnipsel am Start?


    Mein CBM geht ja noch nicht, aber rein in Basic könnte speichern auf Diskette so gehen:

    Code
    10 DOPEN#1,"SCREEN",W
    12 X = Anzahl der zu sichernden Bytes - 1
    14 S = Startaddresse des Bildschirmspeichers
    20 FOR I = 0 TO X 
    30 PRINT#1,CHR$(PEEK(S+I))
    40 NEXT I
    50 DCLOSE#1

    Hallo Holger,

    die Routinen zum Laden und Speichern eines Levels funktionieren bereits- aber sie sind aufgrund der FOR-NEXT-Schleife grottenlangsam. :(

    Deshalb wäre eben eine Maschinenroutine oder ein Trick zum Abspeichern im RAM auf die Schnelle Tour die ideale Lösung!


    Viele Grüsse,
    Matthias

  • Wegen dem Bildschirm "Retten". Wenn es tatsächlich nur um das Beibehalten und nicht ums Abspeichern geht, dann probier doch mal Assembler direkt. Klappt natürlich nur, wenn genug RAM vorhanden ist.

    Die ganz simple Variante wäre jedes Byte des Bildschirmspeichers auslesen und in einen anderen Bereich des RAMs kopieren. Beim Ausblenden des HelpScreens dann wieder genau andersherum.


    Als Tip: Versuche Schleifen zu machen, die zeilenweise auslesen. Noch optimaler wird es, wenn man unterhalb von 256 Bytes bleibt und z.B. gleich 4 Zeilen auf einmal kopiert.


    Der Ablauf in der Schleife ist ungefähr LDA $Bildadresse,X : STA $AndereAdresse,X : INX : Vergleiche ob Länge erreicht.


    Zum Thema laden/speichern bin ich aktuell auch noch nicht zufrieden... ein Level hat gute 17 blocks, da ich den Wert einer jeden Speicherzelle des Bildschirms wegsichere.


    Da gibt es ein schönes Stichwort, was hier vmtl. Super funktioniert. Heißt "Run Length Encoding" (RLE).

    Es bedeutet, daß Du schaust, ob ein SPACE als nächstes kommt und wenn ja, ob das übernächste auch noch ein SPACE ist, und wenn ja, ob das Über-Über-Nächste immer noch ein SPACE ist. Die zählst Du solange durch, bis es dann dochmal ein anderes Zeichen wird ( Blockstein ). Abgespeichert wird dann nicht jedes SPACE einzeln sondern: SPACE + Anzahl wieviel es waren.

    Beim Einlesen weiß man dann ja, daß nach einem gelesenen SPACE die Anzahl der zu zeichenenden SPACEs kommt. Beachten muß man nur, daß natürlich beim 8Bit Rechner nur bis 256 gezählt wird, man muß also auch einplanen nach dieser Zahl schonmal ein "SPACE"+256 abzuspeichern und dann mit einem neuen Zähler bei "0" wieder anzufangen.


    Die Levelumrandung wird natürlich gar nicht mitgespeichert, wenn es eine gibt ("*").

    -- 1982 gab es keinen Raspberry Pi , aber Pi und Raspberries

  • Muss man den Bildschirm denn wirklich zwischenspeichern?


    Wenn man eine zentrale Routine hat, die den Bildschirm aufbaut, dann muss man ihn nicht zwischenspeichern.


    - Bildschirm löschen

    - Hilfeschirm anzeigen

    - auf Taste warten

    - Bildschirm löschen

    - zentrale Bildschirm Routine starten

  • Guten Morgen Burschen!


    Zum Thema Assembler: Ich wüsste nichtmal, wie ich einen starte, geschweige denn, welchen man da nimmt. ;)

    Von der Architektur eines 6502 habe ich nicht den Funken Ahnung- wirklich. Ich bin nicht mal in der Lage, dezimal in hex umzuwandeln... (und verstehe auch nicht, weshalb man überhaupt hex verwendet ::cry::)

    Will sagen:

    Mein Basic-Leveleditor funktioniert soweit super- die Routine zum speichern werde ich noch abändern, indem ich den Bildschirm zeilenweise in einen String ablege (+der optimierten Kapazitätsverbesserung bei sich wiederholenden Zeichen).

    Hierzu hab ich vor einiger Zeit mit DATA-Zeilen gespielt, welche den Code des Zeichens, gefolgt von der Anzahl dieser, hintereinander einlesen und auf den Bildschirm bringen. Quasi diesese RLE, von dem ThoralfAsmussen oben schreibt. :) Das klappt eigentlich alles soweit gut- bis auf die Geschwindigkeit beim AUFBAU des Levels.

    Das geschieht in einer FOR-NEXT-Schleife und dauert lange.

    Durch PETSPEED kann dies auf akzeptable Zeiten beschleunigt werden- aber bei einem Lebensverlust müsste ich wieder den Teil neu aufbauen, welcher durch den Text überschrieben wurde... bzw. eben im Leveleditor beim Umschalten des Bildschirms in den Hilfescreen und zurück.

    Deshalb die Idee mit dem "schnellen" speichern/laden im RAM.

    Allerdings bekomme ich da sicher kein Assembler hin... bzw. wüsste nicht, wie ich da anzufangen hätte.


    Diddl : Was meinst du mit "zentraler Bildschirm Routine"? Der Aufbau des Levelrandes, etc... passiert eh mit so einer Routine- aber das geht flott, weils eben nur der Rand ist. Um das ganze Level nach Wechsel in einen anderen Bildschirminhalt neu darstellen zu können, bräuchte ich deutlich schnellere Varianten, als mit FOR-NEXT. :( Sonst nervt das Spiel, es soll ja flüssig zu spielen sein.


    Viele Grüsse und DANKE euch für all den Input- evtl. bekommen wir's gemeinsam hin? angst

    Matthias

  • Hex wird einfach verwendet, weil es die platzsparendste Form einer Binärzahl darstellt. Schliesslich war gerade zu Beginn der 8 Bit Computerzeit der Platz auch auf dem Bildschirm oft begrenzt. Z.B. VC-20 mit 23 Zeichen pro Zeile...

    Du musst auch weniger tippen, wenn Du es in Hex eingibst.

  • Ich würde mir den Source ja gerne ansehen, aber ich traue mich nicht, einen CBM einzuschalten, weil der 720 nach 15 Minuten im Netzteil Silvester feierte.

    LIEBER NICHT! ;)

    Erstmal das Nötigste prüfen und überholen. Nach dem Lockdown gehen wir das mal an, damit du wenigstens erstmal ein komplett voll funktionsfähiges Set bei dir stehen hast.

  • Ich würde mir den Source ja gerne ansehen, aber ich traue mich nicht, einen CBM einzuschalten, weil der 720 nach 15 Minuten im Netzteil Silvester feierte.

    Seufz.. das macht man ja auch nicht, wenn man nicht VORHER mal die original verbauten Netzfilter-Kondensatoren im Netzteil angeschaut hat. Zu 99% haben die nämlich die besagten Alterungsrisse, durch die sie innerhalb einer relativ kurzen Frist nach Einschalten effekt- und duftvoll abrauchen. Da passiert aber meist nicht mehr als eben *pfffffft...* und *bäh!*, deshalb einfach austauschen, dann geht alles wieder. Und halt am besten schon vor dem Einschalten prüfen und umlöten - die Austauschkondensatoren kosten da nicht die Welt, und zusätzlich kann man auch gleich die Elkos ersetzen, da die auch seeeehr häufig platt sind. Hab ich grad bei meinem CBM 720 erledigt, als nächstes ist der CBM 710 dran.


    Altbekanntes Thema aber. Nach meinen bisherigen Erfahrungen scheint bislang eine der größten Raritäten im Computerbereich nicht ein bestimmtes Gerät zu sein, sondern ein golden-teiltransparenter RIFA-Netzfilter im Netzteil eines Retro-Geräts *ohne Alterungsrisse*... ::vodoo:: (und nein, bitte jetzt keine Bilder solcher "Raritäten" hier posten, der Thread soll damit nun nicht zugespammt werden!)

  • Welche möglichen Inhalte kann denn eine Position Deines Levels / Leveleditors auf dem Bildschirm haben? Nur "Wand oder leer"? Oder noch weitere andere Zeichen pro Position? Und die Spielfeldbegrenzung (Außenrand) ist ebenfalls dann ein "Wand"-Zeichen, oder?

  • Juhu,


    grob sähe die Aufbauroutine des Levels so aus:


    10 for a=121 to 960

    20 poke 32768+a, t(a)

    30 next a


    "t" speichert hier den Code eines jeden einzelnen Zeichens. Das ist die "grobe" Variante.

    Aber hierzu müsste "t" sehr groß dimensioniert werden- UND: die Schleife ist LAAAAANGSAM in Basic.


    Beim Sichern eben andersrum:


    10 for a=121 to 960

    20 t(a)=peek(32768+a)

    30 next a


    Das Level beginnt also ab Zeile vier, bis Zeile 24 am CBM mit 40 Zeichen Bildschirm, und hat einen Rand links und rechts.


    Wie gesagt, dies bezieht sich nur auf den Leveleditor. Im Spiel verwende ich aktuell noch "statische" Levels, welche mittels normalen PRINT-Befehlen direkt im Listing realisiert sind. Der Reiz besteht jedoch darin, die Levels nachladen und vor allem selbst designen zu können. Deshalb der Leveleditor mit späterem Umbau des Spiels auf Laderoutinen.

    Das klappt alles wie gesagt echt gut- aber LANGSAM.

    Nachdem ich dann im Leveleditor den Plan eines Hilfescreens hatte, kam mir der Gedanke des Wegsicherns über irgendeine "schnelle" Routine, um zwischen zwei Inhalten hin- und herschalten zu können.

    Diese Methode könnte man dann auch für viele andere Anwendungen verwenden, in denen es auf schnelles Umschalten ankäme.


    Leider funzt auf meinem Hauptrechner VICE nicht, so dass ich hier keine Screenshots zeigen kann- bislang läuft das Spiel schon ganz gut, man hat drei Leben, sieben Level und eine Highscore-Liste. Aber ich möchte es erst noch verfeinern, um es dann zur Verfügung stellen zu können. :)


    Viele Grüsse,

    Matthias

  • H Matthias,


    hast Du mal irgendwie eine Zeichnung des Labels? Welche "Bausteine" kommen vor? Wand, Gegner, Türen, ect? Liegt das Level schon im Speicher oder muss dieses von Disk geladen werden? Evtl. kann ich Dir eine Assembler-Routine programmieren.


    Beste Grüße

    Marco

    Ich suche: Atari 800, MPF-IP

  • Ich fragte deshalb nach der Anzahl möglicher verschiedener Symbole im Bereich des Spielfelds, weil man da ggf. einiges ausnutzen *könnte*. Bei simplem "Wand oder Nicht-Wand" könnte man das gesamte Spielfeld in 105 Bytes kodiert unterbringen, und das Kodieren und Dekodieren wäre in Assembler recht einfach machbar. Bei 4 verschiedenen Symbolen (inkl. Leerzeichen) wäre das Spielfeld in 210 Bytes ablegbar, bei 16 Symbolen immerhin noch in 420 Bytes. Und Assembler ist so schnell und speichereffektiv, dass auch die notwendigen Routinen kaum Rechenzeit fressen.


    Erläuterungsansatz:

    Man speichert für jede Bildschirmposition nur einen Code für eines der möglichen Zeichen - sind nur 2 Symbole vorgesehen, reicht ein einzelnes Bit. "0" wäre in dem Fall z.B. dann das Leerzeichen, "1" die Wand. Über die Bitshift-Befehle des 6502 lassen sich jeweils 8 dieser Bits zu einem Byte zusammenpacken. Beim Wiederherstellen schiebt man einfach die Bits wieder eins nach dem anderen aus den eingelesenen / abgelegten Bytes raus und setzt je nach Ergebnis (Bit steht dann im Carry-Flag, kann man über BCC / BCS prüfen) an der jeweils aktuellen / nächsten Bildschirmposition für "0" ein Leerzeichen, für "1" eine Wand. Nach 8x Bitschieben (innere Schleife) nimmt man sich dann das nächste Byte vor, bis der Bildschirm gefüllt ist (äußere Schleife).


    Bei mehr verfügbaren Symbolen generiert man aus einer Zeichentabelle einen Index, der dann eben "1 von 4 Zeichen" oder "1 von 16 Zeichen" gemäß einer Tabelle repräsentiert. Ersteres verwendet 2 Bit, dann gehen 4 Positionen in ein Byte, Letzteres nutzt 4 Bit ( = ein Nibble), reicht also für 2 Zeichenpositionen in einem Byte. Bei 4 Bit pro Zeichen kann man sich dann auch das bitweise Rollen (fast) komplett sparen, weil man über "AND #$0F" den ersten Tabellenindex und danach über 4x "LSR A" den zweiten Tabellenindex ermitteln kann... (natürlich brauchst Du noch ein paar weitere Assemblerbefehle dazu, aber es ging mir erstmal um die Einfachheit der Logik in der Kodierung; die Auswertungsroutinen sind programmtechnisch relativ trivial..)

  • Hex wird einfach verwendet, weil es die platzsparendste Form einer Binärzahl darstellt. Schliesslich war gerade zu Beginn der 8 Bit Computerzeit der Platz auch auf dem Bildschirm oft begrenzt. Z.B. VC-20 mit 23 Zeichen pro Zeile...

    Du musst auch weniger tippen, wenn Du es in Hex eingibst.

    Ähm, nein. Sondern weil man das im Kopf in Binär umwandeln kann. Und weil alle modernen Computer als Speicherbreite ein Vielfaches von 8 Bit verwenden. Das ist genau eine Hex-Ziffer.

    Als Computer noch üblicherweise ein Vielfache von 3 als Speicherbreite hatten (12 Bit, 18 Bit, ...) wurde das Oktal-System verwendet, weil 3 Bit genau einen Octal-Ziffer darstellen. Oktal ist nicht platzsparender als Dezimal.

    • i-Telex 7822222 dege d

    • technikum29 in Kelkheim bei Frankfurt

    • Marburger Stammtisch

    Douglas Adams: "Everything, that is invented and exists at the time of your birth, is natural. Everything that is invented until you´re 35 is interesting, exciting and you can possibly make a career in it. Everything that is invented after you´re 35 is against the law of nature. Apply this list to movies, rock music, word processors and mobile phones to work out how old you are."

  • OK, das klingt schon wieder nach Hardcore-Coden 😊


    Ich hätte tatsächlich ab irgendeiner Adresse die Bytes ausgelesen und dementsprechend als "Zeichen" interpretiert. Da hast Du tatsächlich von 00 bis ff mögliche Zeichen (für ein sehr gestalterisch umfangreiches Level 😅). Deine Tricks ...d.h. das ich noch viel lernen kann.


    Beste Grüße

    Marco

    Ich suche: Atari 800, MPF-IP

  • Was meinst du mit "zentraler Bildschirm Routine"? Der Aufbau des Levelrandes, etc... passiert eh mit so einer Routine- aber das geht flott, weils eben nur der Rand ist. Um das ganze Level nach Wechsel in einen anderen Bildschirminhalt neu darstellen zu können, bräuchte ich deutlich schnellere Varianten, als mit FOR-NEXT. :( Sonst nervt das Spiel, es soll ja flüssig zu spielen sein.

    Eine zentrale Routine, die das ganze Spielfeld neu aufbaut.


    Muss ja nicht schnell sein.

    Nachdem man die Hilfe gelesen hat, kann sich das Spielfeld ja wieder langsam aufbauen.

    Und irgendwo: "drücken Sie 'W' um weiter zu spielen ..."

  • So, ich hab mal im "Quick-and-dirty"-Modus den theoretischen Ansatz für das Sichern und Zurückschreiben des Spielbildschirms in Assembler umgesetzt.

    Code ist weitgehend kommentiert, die Vorgaben ebenfalls. Ich bin mal von maximal 16 verschiedenen Elementen / Symbolen auf dem Bildschirm ausgegangen und habe daher eine "2-Bildschirmbytes-in-1-Sicherungsbyte"-Kodierung verwendet.


    Keinerlei Anspruch auf Fehlerfreiheit, weil ich grad keine Chance zum Ausprobieren habe. Der Code sollte aber keine groben Böcke mehr haben. Er ist aber natürlich nicht zwingend syntax-korrekt für einen Assembler vorbereitet, was Variablen und Sprunglabel-Format (hier mit führendem ":") anbetrifft. Sollte sich aber verstehen und umsetzen lassen - darauf kommt es an, denke ich...


    Fragen - gerne! Korrekturen - auch!


    Grüße aus Frankfurt,

    Ralph.


  • Sieht so aus als würde das gut gehen.

    Aber Anfängerfreundlich ist anders, irgendwie.


    Zu dem Hilfetext gibt es auch noch so ein Variante, die evtl auch komplett ohne Speichern des Bildschirmes auskommt. Zumindest nicht in so einem Sinn, daß man das wirklich in gut auch als Level wegspeicherbare Sachen "komprimiert", wobei das natürlich eleganter ist.


    Hier mal die einfache Variante für's Überblenden, allerdings auch mit bißchen mehr "Zauber" als nötig.


    -- 1982 gab es keinen Raspberry Pi , aber Pi und Raspberries

  • Jungs!


    Nicht, dass ihr denkt, es interessiert mich nimmer- weil ich hier nicht schreib.

    Ich bin nur total verwirrt, grad. angst:cry2:


    WIE zum Henker müsste ich diese Programmbeispiele eintippen/kompilieren/anwenden?

    WAS bedeutet beispielsweise "Pufferspeicher liegt bei $1C00? :D HILFE?!

    Ich kapier nicht, wie ich hex (ist es hex?) in normale Zahlen umwandle... also $1C00 =?


    Ihr müsst euch vorstellen, dass ich diesen Rechner zwar zu 50% "elektronisch" verstehe- programmiertechnisch jedoch ausschließlich Basic anwenden kann, und da auch nur relativ rudimentär. Ohne einen Hauch Hintergrundwissen, wo welche Adressen von der CPU genutzt werden, und wie das alles zusammenhängt, wird es nicht einfach. :( Hab auch schon oft versucht, dahinterzusteigen (gibt ja gute Videos zur Architektur von sowas)- aber es will nicht in die graue Masse, weil PRAKTISCHE Beispiele an exakt der angewendeten Hardware fehlen.


    Was ich über den Leveleditor noch schreiben kann:

    Verwendet werden kann das komplette PETSCII-Arsenal, auf Kollision wird nur bei der Schlange selbst und bei den Levelrändern geprüft. Somit verwende ich in Hindernissen auf dem Spielfeld als Umrandung das gleiche Grafiksymbol, wie für die Ränder. ;)

    Außerdem kann man einen Levelhintergrund einstellen (anstelle von Leerzeichen). Diese werden hinter der Schlange wieder gezeichnet, klappt auch alles super bereits.

    Mein gestriger Ansatz für den Leveleditor in Basic sieht nun so aus:

    Level wird gezeichnet, dann kann man es sichern. Hierzu wird mit PEEK der Schirm abgefahren und die gelesenen Zeichen in ASCII-Codes umgewandelt, welche in einer Variable (bspw A$(n)) gesichert werden sollen(wobei ich da festgestellt habe, dass inverse Zeichen nur über einen Trick möglich sind und die Adressen nicht 1:1 übereinstimmen).

    Die Routine zur Umwandlung der aus PEEK gelesenen Werte in CHR$ (um es zu einem String aus 38 Zeichen zusammenbauen zu können) muss noch erfolgen.

    Danach würde ich einfach 21 Strings á 38 Zeichen auf Diskette/SD-Karte sichern und im Spiel dann wieder einlesen. Das geht zackig, weil ich aktuell so schon den Hintergrund zeichne (Schleife + PRINT "HINTERGRUND (38 Zeichen)" ).


    Was wie gesagt noch fehlt, ist die Möglichkeit, ALLES, was auf dem Bildschirm zu sehen ist, in sehr kurzer Zeit wegzusichern (im RAM) und wieder zu lesen, um zwischen zwei Seiten quasi hin- und herschalten zu können. (Hilfescreen im Leveleditor bspw.)

    Irgendwo dachte ich mal aufgegriffen zu haben, dass das der CBM mit Basic 4.0 eh schon kann? War aber wohl nur eine Verwechslung mit dem 8000er und dieser Fensterfunktion.

    Im Spiel benötige ich diese Funktion nicht, weil ich da eh Level für Level nachladen lasse (wenn die Routinen dann soweit funktionieren).


    Vielleicht könnten wir mal eure Assemblervorschläge einfach testen? Dazu müsste ich nur Schritt für Schritt wissen, WO ich das eintippe (also welche Software ich dazu auf dem CBM benötige), und WIE ich das kompiliere und dann aufrufe.

    So würd ich's wohl dann langsam kapieren, eben weil ich es PRAKTISCH anwenden kann.


    Viele Grüße und echt VIELEN VIELEN Dank für all euren Input und die Ideen,

    Matthias

  • Ich kapier nicht, wie ich hex (ist es hex?) in normale Zahlen umwandle... also $1C00 =?

    Am einfachsten in dem Du den Windows Calculator startest und auf "Programmier" stellst, dann kannst Du die Zahlensysteme umstellen. Oder halt per Website:

    https://www.binaryhexconverter.com/hex-to-decimal-converter

    https://www.hexadecimaldictionary.com/hexadecimal/0x1C00/


    Einmal editiert, zuletzt von Dekay ()

  • Hier der zweite Link nochmal , damit es gleich klickbar ist.

    https://www.hexadecimaldictionary.com/hexadecimal/0x1C00/


    Ich benutze für sowas einfach einen normalen Taschenrechner, der so einen Modus hat. Aber auch die Desktop Taschenrechner in Software können das üblicherweise, auch wenn man es manchmal erst "freischalten" muß ( Scientific Mode oder so ).


    Ansonsten ist es eigentlich, so, daß man das sich i.a. viel besser einfach als HEX Zahl "denkt". Also gar nicht erst versucht das umzurechnen. Dazu muß man sich mal anschauen, wie das Zahlensystem gedacht ist, aber das ist eigentlich nicht schwierig, es funktioniert ganz normal nur eben mit ein paar mehr Ziffern als üblich.

    Wenn man das macht ist man oft auch viel näher an der Einteilung solcher Rechner dran und man kapiert bestimmte Grenzen besser und einfacher.


    Zum Beispiel: Der 8Bit Rechner kann 65536 Bytes adressieren. Das sind HEX $10000 bzw. als letzte möglich Adresse die $FFFF . Und wenn man jetzt weiß, das $F für 15 steht ist das also, wegen 0 bis 15, genau 16 hoch 4.

    Viel interessanter ist aber, daß die Hälfte von 16 eine 8 ist - und da die ja genauso in HEX als Ziffer benutzt wird, ist als die Hälfte der adressierbaren Adressen bei $8000. DAS ist nun aber eine interessante Sache für Deinen PET, weil Du ja schon von oben die $8000 als Adresse für den Bildschirm kennst. Der Bildschirminhalt wird da also genau auf der Mitte des maximal möglichen RAMs dargestellt.

    Sowas merkt sich als $8000 viel (!) einfacher, als der entsprechende Dezimalwert.


    Und das geht dann z.B. weiter mit $100 , was quasi die kleinste Einheit ist, die man mit einer 8Bit Zahl durchzählen kann. Nämlich 256. Und wenn man z.B. einen Bildschirm mit 40x25 Zeichen hat, dann sind das ja quasi auch 4x250, und damit weiß man, daß man dafür ungefähr ca. 4x $100 Adressen braucht - nur für die Bildschirmdarstellung.

    Wenn man diese $400 Adressbytes irgendwo reservieren will, so daß sie an einem halbwegs sinnvollen Ende liegen, dann kann man z.B. die $2000 als Grenze nehmen, was dann quasi so einen Minimalausbau des Gerätes mit 4KB sind und davon nun ganz einfach 4x $100 zurückrechnen, also $400 von $2000 abziehen.

    Und das ist dann erstmal gewöhnungsbedürftig, weil andere Notation, aber da kommen dann heraus :

    $2000 - $100 = $1F00 ; nochmal $1F00 - $100 = $1E00 ; nochmal $1E00 - $100 = $1D00 ; und noch ein viertes Mal $1D00 - $100 = $1C00

    und siehe da, den Wert solltest Du oben auch schon gesehen haben. Rechnet sich so wesentlich einfacher.


    Und ähnliches gilt auch für die Sachen mit den 16 Werten die der Ralph_Ffm da für die Abspeicherroutine benutzt. Das sind dann eben einfach die Zahlen $0 bis $F und davon kann man in einem Byte quasi 2 Stück unterbringen, nämlich eine "vorn" und eine "hinten" ( als high bzw- low Nibble ). Zusammen sind es dann $FF. Das mit Dezimalzahlen auszuschreiben wird dann richtig schwierig.



    WIE zum Henker müsste ich diese Programmbeispiele eintippen/kompilieren/anwenden?

    WAS bedeutet beispielsweise "Pufferspeicher liegt bei $1C00?


    Nochmal explizit dazu was. Pufferspeicher heißt, daß man da was hineintut an Zahlen. Und der Pufferspeicher muß natürlich genau wie z.B. der Bildschirmspeicher oder der Speicher für das BASIC Programm irgendwo im RAM eine Anfangsadresse haben, und natürlich auch eine Länge bzw. eine Endadresse. Wenn der Puffer bei $1C00 beginnt ist das das, was damit gemeint ist, daß er bei $1C00 liegt. Die Startadresse ist also die $1C00.

    Dazu ist dann noch wichtig, wie groß er ist, damit man da nicht was anderes weiter oben reinschreibt. Bei einer Größe von 4x $100 = $400 ist also der Bereich von $1C00 bis $1FFF ( also ein genau Byte vor $2000 ) der gesamte Pufferbereich.


    Interessant ist das v.a., weil Dein BASIC Programm ja irgendwo "unten" im Speicher liegt und z.B. bei $800 oder $1000 oder ähnliches beginnt. Das BASIC wird man nicht so einfach ändern können. Aber, wenn Du z.B. 32 KB RAM verbaut hast, dann hättest Du ja RAM von $0000 bis $7FFF ( also ein Byte vor der Hälfte von 64KB, nämlich bei $8000 ). Und dann wäre es z.B. extrem sinnvoll, den Puffer weiter oben zu nutzen. Der könnte dann z.B. bei $7C00 beginnen - und man könnte dann auch sagen, der Puffer "liegt" bei $7C00.

    Dem Maschinenprogramm ist sowas i.a. egal, v.a. weil man es ja selbst auch anpaßt. Es hat aber dann den großen Vorteil, daß das BASIC Programm länger sein kann, weil es eben nicht so schnell den kompletten Speicher bis $7C00 gefüllt hat, wogegen die $1C00 schnell mal erreicht ist.

    Und: der Puffer kann natürlich auch an jeder beliebigen anderen Stelle beginnen. Etwa bei $4000 oder $6400 oder ...


    Das gleiche Thema hast Du auch bei der Abspeicherroutine. Dort versteckt sich das aber ein bißchen. Die letzte Zeile von dem Programm reserviert aber auch einen Pufferspeicher.

    Code
    :Sicherungsspeicher 
    .BYTE    (420x $00)


    Der Unterschied ist hier nur, daß die Adresse nicht fix festgelgt ist, sondern eben die 420 Bytes einfach direkt am Ende vom Programm angeschlossen werden.




    Und wie gibt man sowas nun ein ??


    Normalerweise benutzt man dafür einen Assembler. Das ist ein Prgramm, was Maschinensprachkommandos versteht und zusätzlich aber bestimmte Adressberechnungen automatisch machen kann. Deshlab kann man dann einfach sowas wie :Sicherungsspeicher oder .loop1 da reinschreiben und beim Übersetzen ermittelt der Assembler, an welcher Adresse im Speicher das nun genau ist - und setzt den Wert dann z.B. dort ein wo ein Sprung auf dieses "Label" steht.


    Der Vorteil ist, daß man sich beim Programmschreiben noch nicht festlegen muß, wo genau im RAM das Programm mal liegen soll.


    Wer es handfester mag, kann das auch mit einem sogenannten "Monitor" eingeben. Natürlich am Besten mit einem der auch Assemblerbefehle versteht. Der Monitor macht ber z.B. diese Adressberechnungen NICHT und man muß dort selber die richtigen Adressen einsetzen.


    Du brauchst also für Deinen PET einen a.) Assembler oder b.) Monitor

    Welche da gut sind, kann ich mangels PET nicht sagen. Woanders gab es HypraAss oder GigaAssembler oder was auch immer. Die Sachen findet man aber.

    Dort tippst Du die Sachen ein und mußt noch eine Startadresse mit vorgeben. Dann wird beim Assemblieren das Programm an genau diese Stelle abgelegt und man kann es dann auch direkt aus dem Speicher heraus abspeichern.


    Vielleicht kann ja Jan1980 mal was dazu sagen, was man am PET günstigerweise dafür benutzt,

    -- 1982 gab es keinen Raspberry Pi , aber Pi und Raspberries

  • Ich habe am PET nicht sehr viel in Assembler gemacht. Am C64 selber nutze ich den Turboassembler für kleinere Sachen. Am Atari 800XL den Assembler Editor oder MAC/65. Ansonsten bin ich nach ein paar kleineren Programmen am Endgerät selber dann doch relativ schnell bei Crossassembler gelandet. Für C64 und PET nutze ich CBM-Studio und für den Atari 800XL und das VCS nutze ich WUDSN.


    Beim PET hab ich kleine Programme auf Papier geschrieben und diese von Hand assembliert und dann im TIM eingegeben, in HEX versteht sich. Das hat mir viel gebracht und eine ganze Zeitlang konnte ich dann auch gängige opcodes aus dem Kopf. Also zum Lernen ist das eine super Möglichkeit ! Den Tip bekam ich hier im Forum.

    Wenn du einen Basic-Loader schreibst, müssen die Data-Zeilen ja dezimal eingegeben werden. Irgendwie mag ich keine Basic-Loader. Aber wenn jemand unbedingt in Basic programmieren will und zeitkritische Routinen braucht, wird man nicht drum rum kommen. Ich könnte mir gut vorstellen, dass man die ganzen hex-Zahlen in eine Excel-Tabelle reinkopieren kann und diese wandelt das dann in dezimal um, dann schreibt man die Werte ab oder kopiert zurück und ergänzt die Kommata. Ausprobiert hab ich das nie.


    Nochmal zum Thema. Also wie gesagt, von Hand assemblieren und im TIM eingeben. Oder einen Assembler. Hier im Forum hat doch jemand einen tollen Assembler geschrieben für den PET. Mit was ich noch experimentiert hatte und was in meinem 8032 zB drin ist, ist das Batpro-Toolkit. Das ist eine Basic-Erweiterung, ein Assembler und ein Texteditor. Ich lade es hier mal in den Anhang inkl. Anleitung.

    Ich glaube mit dem Monitor und der Basic-Erweiterung kann man bequem DATA Zeilen für einen Basic Loader erzeugen.. Ich hab mir jetzt nicht alles durchgelesen.


    EDIT: Das Batpro-Kit wird in ein Eprom geschrieben, also keine "Soft-Software"... :)


    EDIT2: Ich sehe gerade, Batpro 4.8 ist nur für CBM 8032. CBM_BA bräuchte für seinen 4032 aber Batpro 4.0. Mal schauen, ob sich das auch irgendwo findet...



    Gruß Jan

  • Hi Matthias,


    stell' Dir einfach vor Du hättest 16 Finger. Dann würdest Du nicht von 1 bis 10 sondern von 1 bis F zählen, wobei die zusätzlichen Finger einfach A bis F heißen würden. Erst wenn der erste Finger ein zweites Mal dran ist hast Du die 11.

    Der Vorteil dabei ist, dass Du ein Byte in zwei Hexzahlen wiedergeben kannst: FF = 255


    Guckst Du: https://sps-tutorial.com/hexadezimalzahlen/


    :)Franky


    P.S.: Einen Rechner (den ich seit Jahren einsetze) findest Du hier: https://www.romanblack.com/hexcon.htm

  • Ähm, nein.

    Erklär mir wo der Widerspruch ist. Was moderene Computer tun oder nicht spielt ja hier keine Rolle. Kennst Du ein Zahlensystem wo man binäre 8 Bits kürzer und lesbarer darstellen kann?

    Du hattest geschrieben, dass Hex verwendet wird, WEIL es platzsparender ist als Dezimal. Das ist nicht korrekt.

    Was nicht bedeutet, dass es nicht platzsparender ist. ;)


    Und wenn es um's Platzsparen ginge, warum verwendet man dann nicht gleich ein Zahlensystem, das alle Buchstaben nutzt?

    • i-Telex 7822222 dege d

    • technikum29 in Kelkheim bei Frankfurt

    • Marburger Stammtisch

    Douglas Adams: "Everything, that is invented and exists at the time of your birth, is natural. Everything that is invented until you´re 35 is interesting, exciting and you can possibly make a career in it. Everything that is invented after you´re 35 is against the law of nature. Apply this list to movies, rock music, word processors and mobile phones to work out how old you are."

  • Hexzahlen sind einfach sehr praktisch, weil eine Stelle exakt 4 Bits abbildet.

    Den 16 Bit Adressraum kann man dadurch mit 4 Hexzahlen darstellen.

    Oktal Zahlen haben diesen Vorteil auch (3 Bits pro Stelle), allerdings ist Hex platzsparender in der Darstellung.


    Ich persönlich hab durch Hexzahlen eine bessere Vorstellung als mit Dezimalzahlen (bei digitaler Anwendung).